zoukankan      html  css  js  c++  java
  • drf之序列化组件

    序列化组件:

    1. 序列化,序列化器会把模型对象转换成字典,经过response以后变成json字符串
    2. 反序列化,把客户端发送过来的数据,经过request以后变成字典,序列化器可以把字典转成模型
    3. 反序列化,完成数据校验功能

    序列化类的字段

    字段字段构造方式
    BooleanField BooleanField()  有true、false
    NullBooleanField NullBooleanField()  有null、true、false三个值
    CharField CharField(max_length=None, min_length=None, allow_blank=False, trim_whitespace=True)
    EmailField EmailField(max_length=None, min_length=None, allow_blank=False)
    RegexField RegexField(regex, max_length=None, min_length=None, allow_blank=False)
    SlugField SlugField(max_length=50, min_length=None, allow_blank=False) 正则字段,验证正则模式 [a-zA-Z0-9*-]+
    URLField URLField(max_length=200, min_length=None, allow_blank=False)
    UUIDField UUIDField(format='hex_verbose') format: 1) 'hex_verbose' 如"5ce0e9a5-5ffa-654b-cee0-1238041fb31a" 2) 'hex' 如 "5ce0e9a55ffa654bcee01238041fb31a" 3)'int' - 如: "123456789012312313134124512351145145114" 4)'urn' 如: "urn:uuid:5ce0e9a5-5ffa-654b-cee0-1238041fb31a"
    IPAddressField IPAddressField(protocol='both', unpack_ipv4=False, **options)
    IntegerField IntegerField(max_value=None, min_value=None)
    FloatField FloatField(max_value=None, min_value=None)
    DecimalField DecimalField(max_digits, decimal_places, coerce_to_string=None, max_value=None, min_value=None) max_digits: 最多位数 decimal_palces: 小数点位置
    DateTimeField DateTimeField(format=api_settings.DATETIME_FORMAT, input_formats=None)
    DateField DateField(format=api_settings.DATE_FORMAT, input_formats=None)
    TimeField TimeField(format=api_settings.TIME_FORMAT, input_formats=None)
    DurationField DurationField()
    ChoiceField ChoiceField(choices) choices与Django的用法相同
    MultipleChoiceField MultipleChoiceField(choices)
    FileField FileField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
    ImageField ImageField(max_length=None, allow_empty_file=False, use_url=UPLOADED_FILES_USE_URL)
    ListField ListField(child=, min_length=None, max_length=None)
    DictField DictField(child=)

    选项参数:

    参数名称作用
    max_length 最大长度
    min_lenght 最小长度
    allow_blank 是否允许为空
    trim_whitespace 是否截断空白字符
    max_value 最小值
    min_value 最大值

    通用参数:

    参数名称说明
    read_only 表明该字段仅用于序列化输出,默认False
    write_only 表明该字段仅用于反序列化输入,默认False
    required 表明该字段在反序列化时必须输入,默认True
    default 反序列化时使用的默认值
    allow_null 表明该字段是否允许传入None,默认False
    validators 该字段使用的验证器
    error_messages 包含错误编号与错误信息的字典
    label 用于HTML展示API页面时,显示的字段名称
    help_text 用于HTML展示API页面时,显示的字段帮助提示信息

     

     

     

     

     

     

     

     

     

    Serializer:

    1、写一个序列化类,继承serializer。 ser.py文件如下:

    class BookSerializers(serializers.Serializer):
       #对book表字段进行序列化 b_id
    =serializers.CharField(read_only=True) name=serializers.CharField(max_length=10) price=serializers.DecimalField(max_digits=4,decimal_places=2) author=serializers.CharField(max_length=8,validators=['check_author']) #author字段的校验函数 def check_author(data): if data.startswitch('NQ'): raise ValidationError('名字不能以NQ开头') else: return data #重写update方法,对数据修改的时候,需要用到 def update(self, instance, validated_data): instance.name=validated_data.get('name') instance.price=validated_data.get('price') instance.author=validated_data.get('author') instance.save() return instance #重写create方法,添加数据的时候需要重写 def create(self, validated_data): instance=Book.objects.create(**validated_data) return instance #局部钩子 def validate_author(self, data): if data.startswith('sb'): raise ValidationError('作者名字不能以sb开头') else: return data #全局钩子 def validate(self, validate_data): price=validate_data.get('price') if float(price)>10: return validate_data else: raise ValidationError('价格不能低于10元')

    2、views文件下的视图类代码:

    #实现书籍的单条数据查询和书籍的修改,删除
    class BookView(APIView):
        def get(self,request,pk):
            res = MyRespont()
            book=Book.objects.filter(pk=pk).first()
            #序列化book对象
            book_ser=BookSerializers(book)
            res.get_dic['data']=book_ser.data
            return Response(res.get_dic)
    
        def put(self,request,pk):
            res = MyRespont()  #MyRespont()是自己封装的类
            book=Book.objects.filter(pk=pk).first()
    
            book_ser=BookSerializers(instance=book,data=request.data)
            if book_ser.is_valid():
                book_ser.save()
                res.get_dic['data']=book_ser.data
            else:
                res.get_dic['statu']=101
                res.get_dic['msg']=book_ser.errors
                res.get_dic['data'] = book_ser.data
            return Response(res.get_dic)
    
        def delete(self,request,pk):
            res=MyRespont().get_dic
            Book.objects.filter(pk=pk).first().delete()
            res['msg']='删除成功'
            return Response(res)
    
    
    #实现书籍的添加,查询所有
    class BooksView(APIView):
      # 查询所有书籍
    def get(self,request): res=MyRespont() books=Book.objects.all() #序列化多条数据,需要设置many=True books_ser=BookSerializers(books,many=True) res.get_dic['data']=books_ser.data return Response(res.get_dic) def post(self,request): res=MyRespont() book_ser=BookSerializers(data=request.data) if book_ser.is_valid(): book_ser.save() res.get_dic['msg']='添加成功' res.get_dic['data']=book_ser.data else: res.get_dic['msg'] = '添加失败' res.get_dic['data'] = book_ser.errors return Response(res.get_dic)

    3、路由文件urls下的代码:

    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    from rest_framework.routers import DefaultRouter
    #可以处理视图的路由器
    router = DefaultRouter()
    #将路由器中注册视图集合
    router.register('book', views.BooksViewSet)
    #将路由器中的所有路由信息追加到django的路由表中
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^books/',views.BooksView.as_view()),
        url(r'^book/(?P<pk>d+)$',views.BookView.as_view()),
    ]
    
    urlpatterns += router.urls

    Serializer高级用法:

    '''
    serializers的高级用法:
      source的使用
      SerializerMethodField()的使用
    '''
    #1、可以改字段名字,此时xxx是返回给前端的字段名,字段对应内容还是book.title
    xxx = serializers.CharField(source='title')
    #2、可以.跨表,此时返回的数据是public表的出版社邮箱。
    publish = serializers.CharField(source='publish.email')
    #3、可以执行方法
    pub_date = serializers.CharField(source='test')
    #test是Book表模型中的方法
    '''
    SerializerMethodField()的使用
    它需要有个配套方法,方法名叫get_字段名,返回值就是要显示的东西
    '''
    authors = serializers.SerializerMethodField()  
    def get_authors(self, instance):
        # book对象
        authors = instance.authors.all()  # 取出所有作者
        ll = []
        for author in authors:
            ll.append({'name': author.name, 'age': author.age})
        return ll

     PrimaryKeyRelatedField:反序列化,根据外键来实现

    class OrderSerializers(serializers.ModelSerializer):
        # 将订单里的课程id转化成一个个对象(couser.id1,course.id2)=>(course_obj1,course_obj2)
        course = serializers.PrimaryKeyRelatedField(queryset=Course.objects.all(), write_only=True, many=True)
    
        class Meta:
            model = Order
            fields = ['total_amount', 'subject', 'pay_type', 'course']
            extra_kwargs = {
                'total_amount': {'required': True},
                'pay_type': {'required': True},
            }

    ModelSerializer(序列化模型)

    '''
    #模型序列化
    不需要重新写update方法和crater方法
    '''
    class BookModelSerializer(ModelSerializer):
        class Meta:
            model = Book
            fields = "__all__" #对book表中的所有字段进行序列化
            fields=('name','price','author')#只对指定字段进行序列化
            exclude=('name',) #除了name字段外,其他字段都进行序列化
            extra_kwargs = {
                # 类似于这种形式name=serializers.CharField(max_length=16,min_length=4)
                'price': {'write_only': True},
            }

    关联表字段序列化的三种方式

    1、在序列化文件中,利用source参数进行查询(具体可以参照上面:Serializer高级用这一部分)

    跨表,此时返回的数据是public表的出版社邮箱。
    publish = serializers.CharField(source='publish.email')

    2、在models.py文件中添加

    class Book(BaseModel):
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=32,verbose_name='书名')
        price=models.DecimalField(max_digits=5,decimal_places=2,verbose_name='价格')
        #db_constraint=False,此时,如果删除出版社,对应图书不会被删除,而是出版社字段设置为null
        publish=models.ForeignKey(to='Publish',db_constraint=False,on_delete=models.DO_NOTHING)
        authors=models.ManyToManyField(to='Author',db_constraint=False)
    
        class Meta:
            # db_table='图书表'
            verbose_name_plural='图书表'
        #第三表字段
        @property
        def publish_name(self):
            return self.publish.name
        #第三表字段
        def authors_list(self):
            authors=self.authors.all()
            l=[]
            for author in authors:
                l.append(author.name)
            return l

    3、子序列化:( 先创建关联表的序列化类,再进行子序列化)

    class TeacherSerializer(serializers.ModelSerializer):
        class Meta:
            model = models.Teacher
            fields = ('name', 'role_name', 'title', 'signature', 'image', 'brief')
    
    
    class CourseModelSerializer(serializers.ModelSerializer):
        # 子序列化的方式
        teacher = TeacherSerializer()
    
        class Meta:
            model = models.Course
            fields=[
                'id',
                'name',
                ...,
                'teacher',
                'section_list',
            ]
  • 相关阅读:
    Python Revisited Day 13 (正则表达式)
    Python Revisited Day 06 (面向对象程序设计)
    Python Revisited (变量)
    Python Revisited Day 05(模块)
    Python Revisited Day 04 (控制结构与函数)
    Python Revisited Day 03 (组合数据类型)
    Numpy
    Python Revisited Day 01
    Python3使用openpyxl读写Excel文件
    Python3操作YAML文件
  • 原文地址:https://www.cnblogs.com/nq31/p/13907957.html
Copyright © 2011-2022 走看看