Skip to content

Commit 471c9d1

Browse files
committed
N fix
1 parent a3e7df7 commit 471c9d1

File tree

2 files changed

+17
-15
lines changed

2 files changed

+17
-15
lines changed

md/110-文章分类.md

+16-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
博客文章通常需要分类,方便用户快速识别文章的类型,或者进行过滤操作。
1+
博客文章通常需要分类,方便用户快速识别文章的类型,或者进行某种关联操作。
2+
3+
本章就来实现对文章的分类。
24

35
## 增加分类模型
46

@@ -34,11 +36,11 @@ class Article(models.Model):
3436

3537
```
3638

37-
比较简单的分类模型,大体上就 `title` 字段会用到。
39+
字段很简单,大体上就 `title` 字段会用到。
3840

3941
别忘了数据迁移。
4042

41-
> 教程为了简单起见就把分类的 model 放到 article 目录中了。实际项目应根据情况考虑是否需要另起一个单独的分类 app。
43+
> 教程把分类的 model 放到 article app中了。实际项目应根据情况考虑是否需要另起一个单独的分类 app。
4244
4345
## 视图与路由
4446

@@ -126,26 +128,26 @@ class ArticleSerializer(serializers.HyperlinkedModelSerializer):
126128

127129
先看 `CategorySerializer`
128130

129-
- `HyperlinkedIdentityField` 前面章节有讲过,作用是将路由间的表示转换为超链接。`view_name` 参数是路由的别名,你必须显示指定。 `category-detail` 是自动注册路由时,`Router` 默认帮你设置的详情页面的名称,类似的还有 `category-list` 等,更多规则参考[文档](https://www.django-rest-framework.org/api-guide/routers/#defaultrouter)
131+
- `HyperlinkedIdentityField` 前面章节有讲过,作用是将路由间的表示转换为超链接。`view_name` 参数是路由名,你必须显示指定。 `category-detail` 是自动注册路由时,`Router` 默认帮你设置的详情页面的名称,类似的还有 `category-list` 等,更多规则参考[文档](https://www.django-rest-framework.org/api-guide/routers/#defaultrouter)
130132
- 创建日期不需要后期修改,所以设置为 `read_only_fields`
131133

132-
然后再来看更麻烦一点的 `ArticleSerializer`
134+
再来看 `ArticleSerializer`
133135

134-
- 由于我们希望文章接口不仅仅只返回分类的 id 而已,所以需要显示指定 `category` ,将其变成一个嵌套数据,与之前的 `author` 类似。
135-
- DRF 框架原生没有实现**可写的嵌套数据**(因为其操作逻辑没有统一的标准),那我想**创建/更新**文章和分类的外键关系怎么办?一种方法是自己去实现序列化器的 `create()/update()` 方法;另一种就是 DRF 框架提供了修改外键的一个快捷方式,即显示指定 `category_id` 字段,则此字段会自动链接到 `category` 外键,以便你更新外键关系。
136+
- 由于我们希望文章接口不仅仅只返回分类的 id 而已,所以需要显式指定 `category` ,将其变成一个嵌套数据,与之前的 `author` 类似。
137+
- DRF 框架原生没有实现**可写的嵌套数据**(因为其操作逻辑没有统一的标准),那我想**创建/更新**文章和分类的外键关系怎么办?一种方法是自己去实现序列化器的 `create()/update()` 方法;另一种就是 DRF 框架提供的修改外键的快捷方式,即显式指定 `category_id` 字段,则此字段会自动链接到 `category` 外键,以便你更新外键关系。
136138
- 再看 `category_id` 内部。`write_only` 表示此字段仅需要可写;`allow_null` 表示允许将其设置为空;`required` 表示在**创建/更新**时可以不设置此字段。
137139

138140
经过以上设置,实际上序列化器已经可以正常工作了。但有个小问题是如果用户提交了一个不存在的分类外键,后端会返回外键数据不存在的 500 错误,不太友好。解决方法就是对数据预先进行**验证**
139141

140142
验证方式又有如下几种:
141143

142-
- 覆写序列化器的 `validate()` 方法。这是个全局的验证器,其接收的唯一参数是所有字段值的字典。当你需要同时对多个字段进行验证时,这是个很好的选择。
143-
- 另一种就是教程用的方法,即 `validate_{field_name}` 方法,它会只验证某个特定的字段,比如 `category_id`
144+
- 覆写序列化器的 `.validate(...)` 方法。这是个全局的验证器,其接收的唯一参数是所有字段值的字典。当你需要同时对多个字段进行验证时,这是个很好的选择。
145+
- 另一种就是教程用到的,即 `.validate_{field_name}(...)` 方法,它会只验证某个特定的字段,比如 `category_id`
144146

145147
`validate_category_id` 检查了两样东西:
146148

147149
- 数据库中是否包含了对应 id 值的数据。
148-
- 传入值是否为 None。这是为了能够将已有的外键置空而设置的
150+
- 传入值是否为 None。这是为了能够将已有的外键置空
149151

150152
如果没通过上述检查,后端就抛出一个 400 错误(代替之前的 500 错误),并返回错误产生的提示,这就更友好一些了。
151153

@@ -155,9 +157,9 @@ class ArticleSerializer(serializers.HyperlinkedModelSerializer):
155157

156158
打开命令行,首先创建分类:
157159

158-
> 你创建的数据 id 和博主的不一定相同,不要惊慌这是正常的,因为我在写文章时会反复进行测试,确保正确。再重复一次,如果你更喜欢图形化的界面,请下载 Postman
160+
> 你创建的数据 id 和博主的不一定相同,这是正常的,因为我在写教程时会反复测试,确保正确。
159161
160-
```
162+
```python
161163
C:\...> http -a dusai:admin123456 POST http://127.0.0.1:8000/api/category/ title=Django
162164
...
163165

@@ -214,7 +216,7 @@ C:\Users\Dusai>http -a dusai:admin123456 PATCH http://127.0.0.1:8000/api/article
214216
}
215217
```
216218

217-
这里细心一点的就会发现,我们在更新资源时用到了 `POST``PUT``PATCH` 三种请求方法,它们在 DRF 中的区别是啥
219+
这里细心一点的就会发现,在更新资源时用到了 `POST``PUT``PATCH` 三种请求方法,它们的区别是啥
218220

219221
- `POST` :创建新的资源。
220222
- `PUT` : 整体更新特定资源,默认情况下你需要完整给出所有必须的字段。
@@ -279,4 +281,4 @@ class CategoryViewSet(viewsets.ModelViewSet):
279281
return CategoryDetailSerializer
280282
```
281283

282-
除此之外没有新的魔法,轻松搞定
284+
除此之外没有新的魔法。

md/90-视图集.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ class ArticleViewSet(viewsets.ModelViewSet):
157157
def get_serializer_class(self):
158158
if self.action == 'list':
159159
return SomeSerializer
160-
elseh
160+
else:
161161
return AnotherSerializer
162162
```
163163

0 commit comments

Comments
 (0)