rest_framwork序列化Serializer和ModelSerializer、url生成HyperlinkedIdentityField、深度depth

Serializer:

  自定义错误信息在字段类型中设置error_messages的值

  SerializerMethodField字段类型为自定义显示字段的值,需要构造一个返回字段值的方法,返回值可以为列表、字典、字符串、数字等:get_字段名

  用SerializerMethodField自定义显示时,可以对返回值进行筛选操作

  soure参数,用于自定义显示内容:在关系字段中使用最为适合

  validators参数接收一个列表,列表存放验证类的实例对象,用户判断POST、PUT请求数据是否合规

class PriceValidator:
    def __init__(self, base):
        self.base = base

    def __call__(self, value):
        if value != self.base:
            message = '价格必须大于 %s.' % self.base
            raise serializers.ValidationError(message)

    def set_context(self, serializer_field):
        """
        This hook is called by the serializer instance,
        prior to the validation call being made.
        """
        # 执行验证之前调用,serializer_fields是当前字段对象
        pass


class BookSerializers(serializers.Serializer):
    title = serializers.CharField(error_messages={'required': '书名不能为空'})
    price = serializers.IntegerField(error_messages={'required': '价格不能为空'}, validators=[PriceValidator('18')])
    # publish = serializers.CharField(source='publish.name')  # 一对多字段
    publish = serializers.SerializerMethodField(error_messages={'required': '出版社不能为空'})  # 方法自定义显示
    # publish_id = serializers.IntegerField()
    pub_date = serializers.DateTimeField()
    # authors = serializers.CharField(source="authors.all")  # 多对多字段可以用all取所有对应对象
    authors = serializers.SerializerMethodField()  # 方法自定义显示

    # 自定义publish字段显示信息, 必须用SerializerMethodField方法
    def get_publish(self, obj):  # obj为这本书对象
        data_list = {
            "id": obj.publish.id,
            "name": obj.publish.name,
            "email": obj.publish.email
        }
        return data_list

    def get_authors(self, obj):
        authors_list = []
        authors_queryset = obj.authors.all().filter(age__lt=30)  # 这本书的所有作者,且年龄小于30岁
        for author in authors_queryset:
            authors_list.append(author.name)
        return authors_list

ModelSerializer:

  与Serializer区别在于,前者手动,后者自动。只需要配置元类,其余自定义设置与Serializer并无区别,例如source参数、SerializerMethodField的使用都是一致。

class PriceValidator:
    def __init__(self, base):
        self.base = base

    def __call__(self, value):
        if value != self.base:
            message = '价格必须大于 %s.' % self.base
            raise serializers.ValidationError(message)

    def set_context(self, serializer_field):
        """
        This hook is called by the serializer instance,
        prior to the validation call being made.
        """
        # 执行验证之前调用,serializer_fields是当前字段对象
        pass

class BookSerializers(serializers.ModelSerializer):
    authors = serializers.SerializerMethodField()  # 方法自定义显示
    # publish = serializers.CharField(source='publish.name')  # 一对多字段
    publish = serializers.SerializerMethodField()  # 方法自定义显示
    # role = serializers.CharField(source="get_type_display")
    class Meta:
        model = models.Book
        # fields = "__all__"  # 所有字段默认序列化
        fields = ['title', 'price', 'publish', 'authors']
     # 自定义错误信息
        extra_kwargs = {
                    'title': {"error_messages": {"required": "书名内容不能为空"}},
                    'publish': {"error_messages": {"required": '出版社不能为空'}},
                    'price': {"error_messages": {"required": '价格不能为空'}, "validators": [PriceValidator('18')]}
                }

    # 自定义publish字段显示信息, 必须用SerializerMethodField方法
    def get_publish(self, obj):  # obj为这本书对象
        data_list = {
            "id": obj.publish.id,
            "name": obj.publish.name,
            "email": obj.publish.email
        }
        return data_list

    def get_authors(self, obj):
        authors_list = []
        authors_queryset = obj.authors.all().filter(age__lt=30)  # 这本书的所有作者,且年龄小于30岁
        for author in authors_queryset:
            authors_list.append(author.name)
        return authors_list
class BookView(viewsets.ModelViewSet):
    authentication_classes = [utils.Authentication, ]  # 认证组件,一个列表,类别中放认证类
    permission_classes = [utils.PermissionCheck, ]  # 权限组件, 一个列表, 列表中放权限类
    throttle_classes = [utils.VisitThrottle, ]   # 频率组件
    from rest_framework.parsers import JSONParser, MultiPartParser, FormParser
    parser_classes = [JSONParser, MultiPartParser, FormParser]  # 解析器
    queryset = models.Book.objects.all()  # queryset对象
    serializer_class = serializers.BookSerializers  # 序列化类

HyperlinkedIdentityField:生成url

re_path('^publish/(?P<pk>\d+)', views.PublishDetailView.as_view(), name='publish_detail'),
path('book/', views.BookView.as_view({'get': 'list', 'post': 'create'}),),
class BookSerializers(serializers.ModelSerializer):
    publish = serializers.HyperlinkedIdentityField(view_name="publish_detail", lookup_field='publish_id', lookup_url_kwarg='pk')
     class Meta:
        model = models.Book
        # fields = "__all__"  # 所有字段默认序列化
        fields = ['title', 'price', 'publish', 'authors']

        extra_kwargs = {
                    'title': {"error_messages": {"required": "书名内容不能为空"}},
                    'publish': {"error_messages": {"required": '出版社不能为空'}},
                    'price': {"error_messages": {"required": '价格不能为空'}, "validators": [PriceValidator('18')]}
                }

depth:

  用于关系字段显示多少层,即关系字段下的关系字段的关系字段的关系字段……

class BookSerializers(serializers.ModelSerializer):
    # authors = AuthorsSerializers(many=True)

    class Meta:
        model = models.Book
        # fields = ["title", "price", "publish_id", "pub_date", "authors"]
        fields = "__all__"
        extra_kwargs = {
            'title': {"error_messages": {"required": "书名内容不能为空"}},
            'publish': {"error_messages": {"required": '出版社不能为空'}},
            'price': {"error_messages": {"required": '价格不能为空'}}
        }
        # depth = 1  # 获取表中的多对多字段深度

猜你喜欢

转载自www.cnblogs.com/aizhinong/p/12563203.html
今日推荐