zoukankan      html  css  js  c++  java
  • django restframework Serializers

    序列化器允许将诸如查询集和模型实例之类的复杂数据转换为原生 Python 数据类型,然后可以将它们轻松地呈现为 JSON,XML 或其他内容类型。序列化器还提供反序列化,在首次验证传入数据之后,可以将解析的数据转换回复杂类型。

    REST framework 中的序列化类与 Django 的 Form 和 ModelForm 类非常相似。我们提供了一个 Serializer 类,它提供了一种强大的通用方法来控制响应的输出,以及一个 ModelSerializer 类,它为创建处理模型实例和查询集的序列化提供了有效的快捷方式。

    serializers.Serializer

    举个小栗子

    # app/serializers.py
    from rest_framework import serializers
    from datetime import datetime
    
    class DemoSerializer(serializers.Serializer):
        email = serializers.EmailField()
        content = serializers.CharField(max_length=200)
        created = serializers.DateTimeField()
    
    # app/views.py
    class DemoAPIView(APIView):
        def get(self, request, *args, **kwargs):
            comment = {
                "email":"leila@example.com",
                "content":"foo bar",
                "created":datetime.now()
            }
            serializer = DemoSerializer(data=comment)
    
            serializer.is_valid(raise_exception=True)
            data = serializer.validated_data
            return Response(data=data)
    

    .is_valid() 方法带有一个可选的 raise_exception 标志,如果存在验证错误,将导致它引发 serializers.ValidationError 异常。

    保存实例

    BaseSerializer save源码

        def save(self, **kwargs):
           ...
    
            validated_data = dict(
                list(self.validated_data.items()) +
                list(kwargs.items())
            )
    
            if self.instance is not None:
                self.instance = self.update(self.instance, validated_data)
                assert self.instance is not None, (
                    '`update()` did not return an object instance.'
                )
            else:
                self.instance = self.create(validated_data)
                assert self.instance is not None, (
                    '`create()` did not return an object instance.'
                )
    
            return self.instance
    

      调用自身create,update方法。

    字段验证

    你可以通过向 Serializer 子类添加 .validate_<field_name> 方法来指定自定义字段级验证。这些与 Django 表单上的 .clean_<field_name> 方法类似。

    这些方法只有一个参数,就是需要验证的字段值。

    您的 validate_<field_name> 方法应返回验证值或引发 serializers.ValidationError。

    for example

    # app/serializers.py
    import re
    from datetime import datetime
    from rest_framework import serializers
    
    class DemoSerializer(serializers.Serializer):
        email = serializers.EmailField()
        mobile = serializers.CharField(max_length=11)
        content = serializers.CharField(max_length=200)
        created = serializers.DateTimeField()
    
        def validate_mobile(self, value):
            condition = re.search(r"1[34578][0-9]{9}", value)
            if condition:
                return value
            else:
                raise serializers.ValidationError(
                    "请输入合法的手机号"
                )
    
    # app/views.py
    class DemoAPIView(APIView):
        def get(self, request, *args, **kwargs):
            comment = {
                "email":"leila@example.com",
                "mobile":"12354521541",
                "content":"foo bar",
                "created":datetime.now()
            }
            serializer = DemoSerializer(data=comment)
    
            serializer.is_valid(raise_exception=True)
            data = serializer.validated_data
            return Response(data=data)
    

    对象级验证

    如果要对多个字段进行其他的验证,请将一个名为 .validate() 的方法添加到您的 Serializer 子类中。这个方法只有一个参数,它是一个字段值(field-value)的字典。如果有必要,它应该引发一个 ValidationError,或者只是返回验证的值

    from rest_framework import serializers
    class EventSerializer(serializers.Serializer):
        description = serializers.CharField(max_length=100)
        start = serializers.DateTimeField()
        finish = serializers.DateTimeField()
        def validate(self, data):
            """
            Check that the start is before the stop.
            """
            if data['start'] > data['finish']:
                raise serializers.ValidationError("finish must occur after start")
            return data
    

    处理嵌套对象

    前面的例子适用于处理只具有简单数据类型的对象,但有时还需要能够表示更复杂的对象,其中对象的某些属性可能不是简单的数据类型,如字符串,日期或整数。

    Serializer 类本身就是一种 Field,可以用来表示一个对象类型嵌套在另一个对象类型中的关系。

    class UserSerializer(serializers.Serializer):
        email = serializers.EmailField()
        username = serializers.CharField(max_length=100)
    class CommentSerializer(serializers.Serializer):
        user = UserSerializer()
        content = serializers.CharField(max_length=200)
        created = serializers.DateTimeField()
    

    如果嵌套对象可以是 None 值,则应将 required = False 标志传递给嵌套的序列化类。

    class CommentSerializer(serializers.Serializer):
        user = UserSerializer(required=False)  # May be an anonymous user.
        content = serializers.CharField(max_length=200)
        created = serializers.DateTimeField()
    

    同样,如果嵌套对象是一个列表,则应将 many = True 标志传递给嵌套的序列化类。

    class CommentSerializer(serializers.Serializer):
        user = UserSerializer(required=False)
        edits = EditItemSerializer(many=True)  # A nested list of 'edit' items.
        content = serializers.CharField(max_length=200)
        created = serializers.DateTimeField()
    

    ModelSerializer

    通常你会想要序列化类紧密地映射到 Django 模型定义上。

    ModelSerializer 类提供了一个快捷方式,可让你自动创建一个 Serializer 类,其中的字段与模型类字段对应。

    ModelSerializer 类与常规 Serializer 类相同,不同之处在于:

    它会根据模型自动生成一组字段。

    它会自动为序列化类生成验证器,例如 unique_together 验证器。

    它包含 .create() 和 .update() 的简单默认实现。

    声明ModelSerializer如下所示:

    class AccountSerializer(serializers.ModelSerializer):
        class Meta:
            model = Account
            fields = ('id', 'account_name', 'users', 'created')
    
    class AccountSerializer(serializers.ModelSerializer):
        class Meta:
            model = Account
            fields = "__all__"
    
    class AccountSerializer(serializers.ModelSerializer):
        class Meta:
            model = Account
            exclude = ('users',)
    

      

  • 相关阅读:
    MFC Document/View 3
    MFC Document/View 2
    c++基本类型&&&c++string与c风格字符串的相互转化
    C++不同变量所在内存&&new malloc的区别
    C# 操作Excel 复选框
    prepareStatement与Statement的区别
    Oracle查询用户所有表、字段等信息
    同样的用户和密码,PL/SQL可以正常登录,C#程序却出现 ORA-1017 用户名/口令无效
    javascript原生态的同步异步请求实现
    SQL 数据库是否安全
  • 原文地址:https://www.cnblogs.com/zenan/p/9097565.html
Copyright © 2011-2022 走看看