四、模型類序列化器ModelSerializer
如果我們想要使用序列化器對應的是Django的模型類,DRF為我們提供了ModelSerializer模型類序列化器來幫助我們快速建立一個Serializer類。
ModelSerializer與常規的Serializer相同,但提供了:
- 基於模型類自動生成一系列欄位
- 基於模型類自動為Serializer生成validators,比如unique_together
- 包含預設的create()和update()的實現
4.1 定義
比如我們建立一個BookInfoSerializer
class BookInfoSerializer(serializers.ModelSerializer):
"""圖書資料序列化器"""
class Meta:
model = BookInfo
fields = '__all__'
- model 指明參照哪個模型類
- fields 指明為模型類的哪些欄位生成
我們可以在python manage.py shell中檢視自動生成的BookInfoSerializer的具體實現
>>> from booktest.serializers import BookInfoSerializer
>>> serializer = BookInfoSerializer()
>>> serializer
BookInfoSerializer():
id = IntegerField(label='ID', read_only=True)
btitle = CharField(label='名稱', max_length=20)
bpub_date = DateField(allow_null=True, label='釋出日期', required=False)
bread = IntegerField(label='閱讀量', max_value=2147483647, min_value=-2147483648, required=False)
bcomment = IntegerField(label='評論量', max_value=2147483647, min_value=-2147483648, required=False)
image = ImageField(allow_null=True, label='圖片', max_length=100, required=False)
4.2 指定欄位
4.2.1) 使用fields來明確欄位,__all__
表名包含所有欄位,也可以寫明具體哪些欄位,如
class BookInfoSerializer(serializers.ModelSerializer):
"""圖書資料序列化器"""
class Meta:
model = BookInfo
fields = ('id', 'btitle', 'bpub_date')
4.2.2) 使用exclude可以明確排除掉哪些欄位
class BookInfoSerializer(serializers.ModelSerializer):
"""圖書資料序列化器"""
class Meta:
model = BookInfo
exclude = ('image',)
4.2.3) 預設ModelSerializer使用主鍵作為關聯欄位,但是我們可以使用depth來簡單的生成巢狀表示,depth應該是整數,表明巢狀的層級數量。如:
class HeroInfoSerializer2(serializers.ModelSerializer):
class Meta:
model = HeroInfo
fields = '__all__'
depth = 1
形成的序列化器如下:
HeroInfoSerializer():
id = IntegerField(label='ID', read_only=True)
hname = CharField(label='名稱', max_length=20)
hgender = ChoiceField(choices=((0, 'male'), (1, 'female')), label='性別', required=False, validators=[<django.core.valators.MinValueValidator object>, <django.core.validators.MaxValueValidator object>])
hcomment = CharField(allow_null=True, label='描述資訊', max_length=200, required=False)
hbook = NestedSerializer(read_only=True):
id = IntegerField(label='ID', read_only=True)
btitle = CharField(label='名稱', max_length=20)
bpub_date = DateField(allow_null=True, label='釋出日期', required=False)
bread = IntegerField(label='閱讀量', max_value=2147483647, min_value=-2147483648, required=False)
bcomment = IntegerField(label='評論量', max_value=2147483647, min_value=-2147483648, required=False)
image = ImageField(allow_null=True, label='圖片', max_length=100, required=False)
4.2.4) 顯示指明欄位,如:
class HeroInfoSerializer(serializers.ModelSerializer):
hbook = BookInfoSerializer()
class Meta:
model = HeroInfo
fields = ('id', 'hname', 'hgender', 'hcomment', 'hbook')
4.2.5) 指明只讀欄位
可以通過read_only_fields指明只讀欄位,即僅用於序列化輸出的欄位
class BookInfoSerializer(serializers.ModelSerializer):
"""圖書資料序列化器"""
class Meta:
model = BookInfo
fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment')
read_only_fields = ('id', 'bread', 'bcomment')
4.3 新增額外引數
我們可以使用extra_kwargs引數為ModelSerializer新增或修改原有的選項引數
class BookInfoSerializer(serializers.ModelSerializer):
"""圖書資料序列化器"""
class Meta:
model = BookInfo
fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment')
extra_kwargs = {
'bread': {'min_value': 0, 'required': True},
'bcomment': {'min_value': 0, 'required': True},
}
# BookInfoSerializer():
# id = IntegerField(label='ID', read_only=True)
# btitle = CharField(label='名稱', max_length=20)
# bpub_date = DateField(allow_null=True, label='釋出日期', required=False)
# bread = IntegerField(label='閱讀量', max_value=2147483647, min_value=0, required=True)
# bcomment = IntegerField(label='評論量', max_value=2147483647, min_value=0, required=True)