前言
我們上篇文章使用到了Serializer
類,可能有小夥伴說太過複雜,那麼本篇就為大家帶來更加簡便的序列化類ModelSerializer
ModelSerializer
先來看下ModelSerializer
的程式碼結構如下:
可以看到ModelSerializer
是繼承自Serializer
,官方是這麼介紹到的
ModelSerializer
只是一個常規的Serializer
,只是做了以下事情
- 將自動填充一組預設欄位
- 將自動填充一組預設驗證程式
- 提供了預設的
.create()
和.update()
實現
我們將之前的Serializer
類現在用ModelSerializer
來實現
class StudentModelSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = ['id', 'name', 'age', 'sex']
預設情況下,所有的模型的欄位都將對映到序列化器上相應的欄位。
如果你希望在模型序列化器中使用預設欄位的一部分,你可以使用fields
或exclude
選項來執行此操作
- fields:需要哪些模型欄位
- exclude:排除哪些模型欄位
官方強烈建議你使用fields
屬性顯式的設定要序列化的欄位。這樣就不太可能因為你修改了模型而無意中暴露了資料。
如果我們需要使用模型的全部欄位,則可以將fields
屬性設定成'__all__'
預設情況下,fields
裡的欄位既參加序列化也參加反序列化,如果我們想某個欄位只序列化或反序列化可以定義extra_kwargs
欄位,程式碼如下:
class StudentModelSerializer(serializers.ModelSerializer):
# classes = ClassesModelSerializer(read_only=True)
class Meta:
model = Student
fields = ['id', 'name', 'age', 'sex', 'password']
extra_kwargs = {
"password": {
"write_only": True
},
"id": {
"read_only": False
}
}
上面程式碼如果不寫extra_kwargs
,那麼password
預設參加序列化和反序列化,那麼密碼就會返回給前端了,這裡我們定義了extra_kwargs
欄位,在欄位中設定了password
只能反序列化,那麼使用者只能提交密碼,而後臺不會返回密碼給前臺
當然,extra_kwargs
也可以自定義錯誤資訊,如果業務有需要,可以檢視官方文件
指定巢狀序列化
上面我們都是單模型的序列化,但是實際業務中我們不會這麼簡單,一定會遇到關係模型的序列化,下面我們來講解關係模型的序列化
首先我們看一下models
模型內容:
class Classes(models.Model):
name = models.CharField(max_length=20, verbose_name="班級名")
class Meta:
db_table = "classes"
class Student(models.Model):
SEX_CHOICES = (
(1,'男'),
(2, '女')
)
name = models.CharField(max_length=20, verbose_name='姓名')
age = models.IntegerField(null=True, blank=True, verbose_name='年齡')
sex = models.IntegerField(choices=SEX_CHOICES, default=1, verbose_name='性別')
classes = models.ForeignKey(Classes, on_delete=models.SET_NULL, verbose_name="班級", null=True, related_name='students')
class Meta:
db_table = "student"
我們定義了Student
學生類,裡面定義了一個外來鍵classes
關聯Classes
,一個班級中可以有多個學生,而一個學生只能屬於一個班級,典型的一對多的關係,接下來我們看序列化函式
class ClassesModelSerializer(serializers.ModelSerializer):
class Meta:
model = Classes
fields = ['id', 'name', 'students']
class StudentModelSerializer(serializers.ModelSerializer):
classes = ClassesModelSerializer(read_only=True)
class Meta:
model = Student
fields = ['id', 'name', 'age', 'sex', 'classes']
我們在StudentModelSerializer
中增加了一個額外的欄位classes
,並將欄位設定為只讀,一般外來鍵只做序列化,並且在fields
列表中新增了該欄位。
注意:我們在建立外來鍵模型時,必須在外來鍵中設定related_name
,如果沒設定,序列化時不會返回關聯的外來鍵內容
接下來我們訪問http://127.0.0.1:8000/drf/student/
,會看到返回的學生表中包含了班級表的內容,如下
{
"id": 1,
"name": "jkc",
"age": 18,
"sex": 1,
"classes": {
"id": 1,
"name": "班級1",
"students": [
1,
15,
18
]
}
},