DRF序列化器、模型层路由层、常用字段

DRF序列化器、模型层路由层、常用字段

  • 序列化器-Serializer

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

    序列化器的使用分两个阶段:
        1.在客户端请求时,使用序列化器可以完成对数据的反序列化。
        2.在服务器响应时,使用序列化器可以完成对数据的序列化。
    
  • 视图层views.py

    from django.shortcuts import render
    from app01 import models
    # 导入APIView模块
    from rest_framework.views import APIView
    # 导入自定义序列化类
    from app01.MySerializer import BookSerializer
    # 导入Response
    from rest_framework.response import Response
    
    
    class Bookser(APIView):
        # 查询全部数据
        def get(self, request, *args, **kwargs):
            # 1.查询所有图书对象
            book_list = models.Book.objects.all()
            # 2.序列化 引入自定义序列化类   instance 要序列化的对象  可以单个对象,可以多个, 多个要加many=True
            bs = BookSerializer(instance=book_list, many=True)
    
            # 3.传给前段 统一用Response 里面有一个data参数
            return Response(data=bs.data)
    
    
        def post(self,request,*args,**kwargs):
            #1.反序列化接受的参数  前端传入的数据,在request.data中,是个字典
            ser=BookSerializer(data=request.data)
            print(ser)
            #2.数据校验:如果是True,表示校验通过,直接保存
            if ser.is_valid():
                ser.save()# 调用保存,但是有问题,保存不了,一定要在序列化类中重写某个方法
                return Response(ser.data)
            else:
                return Response(ser.errors)
    
    
    
    class BookDetailSer(APIView):
        # 查询单个字段
        def get(self, request, pk):
            # 1.查询pk对应的数据对象
            book_obj = models.Book.objects.filter(pk=pk).first()
            # 2.序列化
            bs = BookSerializer(instance=book_obj)
            # 3.发送给前端
            return Response(data=bs.data)
    
        def put(self,request, pk):
            #1.查找数据对象
            book_obj=models.Book.objects.filter(pk=pk).first()
            #2.序列化数据对象 前端传入的数据,在request.data中,是个字典
            ser=BookSerializer(instance=book_obj,data=request.data)
            #3.数据校验   记得重写uppdate方法
            if ser.is_valid():
                ser.save()
                return Response(ser.data)
            else:
                return Response(ser.errors)
    
        #删除后返回一个空的
        def delete(self,request,pk):
            models.Book.objects.filter(pk=pk).delete()
            return Response()
    
  • 序列化器文件serializer.py

    #引入Serializer模块
    from rest_framework import serializers
    #导入models
    from app01 import models
    
    from rest_framework.exceptions import ValidationError
    
    
    # 一定要继承一个序列化的基类
    class BookSerializer(serializers.Serializer):
        # 你想序列化哪个字段,就写哪个
        title = serializers.CharField(max_length=8,min_length=3,)
        price = serializers.IntegerField()
        publish = serializers.CharField(max_length=8,min_length=3)
    
    
        # 重写create,使它能够支持新增保存  (派生)
        def create(self, validated_data): #validated_data校验过后的数据
            book=models.Book.objects.create(**validated_data)
            return book   # 一定不要忘了return 对象,否则在视图类中用ser.data 就报错了
    
    
        def update(self, instance, validated_data):
            instance.title=validated_data.get('title')
            instance.price=validated_data.get('price')
            instance.publish=validated_data.get('publish')
            instance.save()
            return
    
    
    
    
    
        # validate_字段名局部钩子     先走字段自己的,再走局部钩子
        def validate_title(self,item):
            print(item)
            #检验规则 需要导入ValidationError
            if item.startswith('lv'):
                raise ValidationError('不能以lv开头')
            return item
    
        #先走局部再走全局
        def validate(self, attrs):
            print(attrs)
            #验证 title和出版社不能相同
            if attrs.get('title')==attrs.get('publish'):
                raise ValidationError('书名和出版社不能相同')
            return attrs
    
    
    
    
    
  • 表模型层 models.py

    from django.db import models
    
    
    # Create your models here.
    
    class Book(models.Model):
        title = models.CharField(max_length=16, default='好书')
        price = models.IntegerField(default=0)
        publish = models.CharField(max_length=32, default='奥特出版社')
    
    
  • 路由层 urls.py

    from django.contrib import admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path('books/',views.Bookser.as_view()),
        path('books/<int:pk>/', views.BookDetailSer.as_view()), #记得加/
    ]
    
    
  • 常用字段

    字段字段构造方式
    BooleanField BooleanField()
    NullBooleanField NullBooleanField()
    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(maxlength=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页面时,显示的字段帮助提示信息
  • 序列化器的反序列化

        #post和put都是反序列化前端发过来的数据
        def post(self,request,*args,**kwargs):
            #1.反序列化接受的参数  前端传入的数据,在request.data中,是个字典
            ser=BookSerializer(data=request.data)
            #2.数据校验:如果是True,表示校验通过,直接保存
            if ser.is_valid():
                ser.save()# 调用保存,但是有问题,保存不了,一定要在序列化类中重写某个方法
                return Response(ser.data)
            else:
                return Response(ser.errors)
            
            
        def put(self,request, pk):
                #1.查找数据对象
                book_obj=models.Book.objects.filter(pk=pk).first()
                #2.序列化数据对象 前端传入的数据,在request.data中,是个字典
                ser=BookSerializer(instance=book_obj,data=request.data)
                #3.数据校验   记得重写uppdate方法
                if ser.is_valid():
                    ser.save()
                    return Response(ser.data)
                else:
                    return Response(ser.errors)
    
  • 模型类序列化器(重要)ModelSerializer

    相对于Serializer 不需要重写create和update #因为内部封装了这两个方法
    序列化,不需要每个字段都写
    class BookModelSerializer(serializers.ModelSerializer):
        class Meta:
            model=models.Book #跟那个表建立关系
            # fields=['title','price'] #要序列化哪些字段
            fields='__all__' #要序列化哪些字段 全部
    
            #了解
            # exclude=['title']  # 除了某个字段除外显示其他
            # depth = 1          # 表关联 查询关联的表的信息 还是只显示id
    
            #校验规则 写在meta类里 额外给某些字段传参数
            # extra_kwargs = {'title': {'max_length': 8, 'min_length': 3},
            #                 'price': {'min_value': 100}}
            #read_only 只读 只序列化 title 这个字段只序列化
            #详细解释 :post请求 传参数时候title这个key传不传值都一样 不会用来写 给用户看 往外走
            extra_kwargs = {'title': {'read_only':True},
                            'price': {'write_only': True}}
            #write_only 只写  只反序列化price 这个字段只写 不做序列化 往数据库写 往里走
    
        #校验规则 重写某个字段 写在外面
        # title=serializers.CharField(max_length=8,min_length=3)
        #
        # #钩子
        # def validate_price(self,price):
        #     if price>300:
        #         raise ValidationError('价格不能大于100')
        #     return price
posted @ 2021-12-22 09:00  迪迦张  阅读(53)  评论(0编辑  收藏  举报