定义
比如我们创建一个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)
指定字段
1) 使用fields来明确字段,__all__
表名包含所有字段,也可以写明具体哪些字段,如
class BookInfoSerializer(serializers.ModelSerializer): """图书数据序列化器""" class Meta: model = BookInfo fields = ('id', 'btitle', 'bpub_date')
2) 使用exclude可以明确排除掉哪些字段
class BookInfoSerializer(serializers.ModelSerializer): """图书数据序列化器""" class Meta: model = BookInfo exclude = ('image',)
3) 显示指明字段,如:
class HeroInfoSerializer(serializers.ModelSerializer): hbook = BookInfoSerializer() class Meta: model = HeroInfo fields = ('id', 'hname', 'hgender', 'hcomment', 'hbook')
4) 指明只读字段
可以通过read_only_fields指明只读字段,即仅用于序列化输出的字段
class BookInfoSerializer(serializers.ModelSerializer): """图书数据序列化器""" class Meta: model = BookInfo fields = ('id', 'btitle', 'bpub_date', 'bread', 'bcomment') read_only_fields = ('id', 'bread', 'bcomment')
添加额外参数
我们可以使用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)
连表查询
1. 在models文件中定义方法, 实现外键表的查找
class Book(BaseModel): name = models.CharField(max_length=64) price = models.DecimalField(max_digits=5, decimal_places=2) img = models.ImageField(upload_to='img', default='img/default.jpg') publish = models.ForeignKey('Publish', on_delete=models.CASCADE) authors = models.ManyToManyField('Author', null=True, ) is_delete = models.BooleanField(default=False) @property def publish_name(self): return self.publish.name @property def authors_name(self): return self.authors.values('name', 'age', 'detail__mobile').all()
- 在多的一方定义方法, 返回查找关联表的数据, 然后使用装饰器
@property
将自定义的方法, 转为属性方法然后在序列化器类中将该属性方法添加到
fields
元组中
2.
class BookModelSerializer(ModelSerializer): publish_addr = SerializerMethodField() def get_publish_addr(self, obj): return obj.publish.address
注意: 使用
SerializerMethodField
定义的属性, 在fields字段中必须声明, 否则会报错
自定义序列化深度连表查询
在使用外键的情况下, 如果想要获取关联表的数据, 除了上面提到的自定义属性外, 还可以在serializers
文件中定义出关联表的类, 然后使用该类来创建字段。从而达到目的, 示例代码如下:
class PublishModelSerializer(ModelSerializer): class Meta: model = models.Publish fields = ('name', 'address') class BookModelSerializer(ModelSerializer): # 自定义连表深度 -- 子序列化方式 publish = PublishModelSerializer() class Meta: model = models.Book fields = ('name', 'price', 'authors_name', 'publish')
注意: 自定义的属性, 也必须在fields字段中声明, 否则会报错
多表反序列化组件
具体和Serializer同理, 示例代码如下:
class BookModelDeSerializer(ModelSerializer): class Meta: model = models.Book fields = ('name', 'price', 'publish', 'authors') extra_kwargs = { 'img': { 'required': True, 'error_messages': { 'required': '图片是必填项' } } } def validate_name(self, value): counts = models.Book.objects.filter(name=value).count() if counts: raise ValidationError({'book_name':'重复的书名'}) return value def validate(self, attrs): publish = attrs.get('publish') name = attrs.get('name') count = models.Publish.objects.filter(name=publish).filter(book__name=name).count() if count: raise ValidationError({'msg': '该出版社存在重复的书名', 'status': 2, }) return attrs
注意:
ModelSerializer
类已经帮我们实现了create
和update
方法。所以我们只需要关注钩子的使用即可视图校验中的
is_valid
的参数raise_exception
的使用book_serializer.is_valid(raise_exception=True)