zoukankan      html  css  js  c++  java
  • Django rest framework 序列化组件

        在笔者认为,在Django rest framework中最重要的是序列化组件,通过序列化我们可以将我们后台数据通过一定格式发送到我们的前端,然后通过一定的方法展示我们的数据。 

        那么我们就开始介绍我们的序列化组件吧!

    自定义字段

    url部分:

    from django.conf.urls import url, include
    from web.views.s6_serializers import TestView
    
    urlpatterns = [
        url(r'test/', TestView.as_view(), name='test'),
    ]
    
    urls.py

    视图部分:

    #!/usr/bin/env python
    # -*- coding:utf-8 -*-
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework import serializers
    from .. import models
    
    
    class PasswordValidator(object):
        def __init__(self, base):
            self.base = base
    
        def __call__(self, value):
            if value != self.base:
                message = 'This field must be %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 UserSerializer(serializers.Serializer):
        ut_title = serializers.CharField(source='ut.title')
        user = serializers.CharField(min_length=6)
        pwd = serializers.CharField(error_messages={'required': '密码不能为空'}, validators=[PasswordValidator('666')])
    
    
    class TestView(APIView):
        def get(self, request, *args, **kwargs):
    
            # 序列化,将数据库查询字段序列化为字典
            data_list = models.UserInfo.objects.all()
            ser = UserSerializer(instance=data_list, many=True)
            # 或
            # obj = models.UserInfo.objects.all().first()
            # ser = UserSerializer(instance=obj, many=False)
            return Response(ser.data)
    
        def post(self, request, *args, **kwargs):
            # 验证,对请求发来的数据进行验证
            ser = UserSerializer(data=request.data)
            if ser.is_valid():
                print(ser.validated_data)
            else:
                print(ser.errors)
    
            return Response('POST请求,响应内容')
    
    views.py
    

      

    基本用法:

    from rest_framework import serializers
    
    class RolesSerializer(serializers.Serializer):
        id = serializers.IntegerField()    #显示的顺序和这里的顺序有关
        title = serializers.CharField()    #我们需要的字段
    
    
    class RolesView(APIView):
    
        def get(self,request,*args,**kwargs):
            #方式一
            # roles = models.Role.objects.all().values('id','title')
            # roles = list(roles)
            # ret = json.dumps(roles,ensure_ascii=False)#序列化,改成False则显示中文,不帮中文编码
    
            #方式二  对于querryset [obj,obj,obj]
            # roles = models.Role.objects.all()
            # ser = RolesSerializer(instance=roles,many=True)#有多条数据 many=True
            # # print(ser.data)#是一个有序的字典
            # ret = json.dumps(ser.data, ensure_ascii=False)
    
            role = models.Role.objects.all().first()
            ser = RolesSerializer(instance=role, many=False)  # 针对单个数据
            # print(ser.data)#是一个有序的字典
            ret = json.dumps(ser.data, ensure_ascii=False)
            return HttpResponse(ret)

      各种字段连接关系的使用:

    class UserInfoSerializer(serializers.Serializer):    #类名和我们的orm没有硬性关系,但是最好是按照数据库的来这样能分清
        user_type1 = serializers.CharField(source="user_type")
        user_type2 = serializers.CharField(source="get_user_type_display")
        username = serializers.CharField()
        password = serializers.CharField()
        gp = serializers.CharField(source='group.title')    #通过.的方式去连外键
        # like = serializers.CharField(source='roles.all ')  多对多的时候不能用这种方式,显示不出来
        #--------------------------------------------#
        rls = serializers.SerializerMethodField()    #多对多使用
    
        def get_rls(self,row):
    
            role_obj_list = row.roles.all()    #字段名
    
            ret=[]
            for item in role_obj_list:
                ret.append({'id':item.id,'title':item.title})
            return ret
    
    class UserInfoSerializer(serializers.ModelSerializer):  #ModelSerializer相比上面的类更简洁
        user_type2 = serializers.CharField(source="get_user_type_display")    #实现自连,为什么实现
        rls = serializers.SerializerMethodField()
        class Meta:
            model = models.UserInfo
            fields = ['id','username','password','user_type2','rls']
    
        def get_rls(self, row):   #自定义显示
            role_obj_list = row.roles.all()    #字段名
    
            ret=[]
            for item in role_obj_list:
                ret.append({'id':item.id,'title':item.title})
            return ret
    

      深度控制以及反向生成URL

    urls.py

    urlpatterns = [
        re_path(r'^(?P<version>[v1|v2]+)/userinfo/$', views.UserInfoView .as_view(),),
        re_path(r'^(?P<version>[v1|v2]+)/group/(?P<pk>d+)$', views.GroupView .as_view(),name='gp'),
        re_path(r'^(?P<version>[v1|v2]+)/group/(?P<pk>d+)$', views.GroupView .as_view(),name='gp'),
    ]
    

      

    views.py

    class UserInfoSerializer(serializers.ModelSerializer):
        group = serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='pk')
        class Meta:
            model = models.UserInfo
            fields = ['id','username','password','group','roles']    #fields是固定的变量,不能自定义
            depth = 0 #深度控制  感觉是向后.一个单位,
    
    class UserInfoView(APIView):
    
        def get(self,request,*args,**kwargs):
            users = models.UserInfo.objects.all()
            ser = UserInfoSerializer(instance=users,many=True,context={'request':request})
            ret = json.dumps(ser.data,ensure_ascii=False)   #防止出现乱码,在序列化的时候添加这个
            return HttpResponse(ret)
    
    class GroupSerializer(serializers.ModelSerializer):
        # group = serializers.HyperlinkedIdentityField(view_name='gp',lookup_field='group_id',lookup_url_kwarg='xxx')
        class Meta:
            model = models.UserGroup
            fields = '__all__'
            # fields = ['id','username','password','group','roles']    #fields是固定的变量,不能自定义
            depth = 0 #深度控制  感觉是向后.一个单位,
    
    class GroupView(APIView):
    
        def get(self,request,*args,**kwargs):
            pk = kwargs.get('pk')
            obj = models.UserGroup.objects.filter(pk=pk).first()
            ser = GroupSerializer(instance=obj,many=False)
            ret = json.dumps(ser.data,ensure_ascii=False)
    
            return HttpResponse(ret)
    

      

    序列化验证系列

    源码流程

  • 相关阅读:
    JAVA自学笔记13
    非常不错的一款打字代码效果
    诡异的python文件
    Linux 虚拟机 docker 上 搭建 python 机器学习 平台
    git无法pull仓库: refusing to merge unrelated histories
    Python
    28 Jupyter Notebook tips, tricks, and shortcuts[Re-post]
    What is the best way to calculate a checksum for a file that is on my machine?
    Building MAPI Applications on 32-Bit and 64-Bit Platforms
    Linux 查看进程 关闭进程
  • 原文地址:https://www.cnblogs.com/swearBM/p/10458797.html
Copyright © 2011-2022 走看看