• Django Rest Framework --序列化、请求数据校验


    序列化

    基本代码结构

    modles.py

     1 from django.db import models
     2 # Create your models here.
     3 
     4 # Create your models here.
     5 class UserGroup(models.Model):
     6     title=models.CharField(max_length=32)
     7 
     8 class UserInfo(models.Model):
     9     user_type_choices=((1,'普通用户'),
    10                        (2,"VIP"),
    11                        (3,"SVIP"))
    12     user_type=models.IntegerField(choices=user_type_choices)
    13     group= models.ForeignKey('UserGroup',on_delete=models.CASCADE,null=True)
    14     roles=models.ManyToManyField('Role')
    15     username=models.CharField(max_length=32,unique=True)
    16     password=models.CharField(max_length=32)
    17 
    18 class UserToken(models.Model):
    19     user=models.OneToOneField(to='UserInfo',on_delete=models.CASCADE)
    20     token=models.CharField(max_length=64)
    21 
    22 class Role(models.Model):
    23     title=models.CharField(max_length=32)
    models.py

    urls.py

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

    views.py

    class UserinfoSerializer(ModelSerializer):
        # user_type = serializers.CharField(source='get_user_type_display')
        # role = serializers.SerializerMethodField()
       #生成url group=serializers.HyperlinkedIdentityField(view_name='gu',lookup_url_kwarg='xxx',lookup_field='group_id') class Meta: model=models.UserInfo fields='__all__' # fields=['id','username','user_type','role'] depth=1 # def get_role(self, row): # roles=row.roles.all() # dict=[] # for item in roles: # dict.append({'ID':item.id,"title":item.title}) # return dict class TestView(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) #方法二 # roles=models.Role.objects.all() # ser=RoleSerializer(instance=roles,many=True) # ret = json.dumps(ser.data, ensure_ascii=False) uesr=models.UserInfo.objects.all()
         #生成url时,必须添加context参数 ser=UserinfoSerializer(instance=uesr,many=True,context={'request': request}) ret = json.dumps(ser.data, ensure_ascii=False) return HttpResponse(ret)

      源码分析

    1.实例化Serializer对象时,many参数的作用?

    我们从实例化入手,大家知道在实例化时,首先执行的是__new__方法,然后返回对应的对象实例,所以我们一步步深入,在BaseSerializer类中找到了__new__方法。

     

    根据判断many参数的值,来确定我们需要返回的对象实例。

    2.Serializer对象是如何序列化数据的?

    从data方法入手,进入data方法,返回self._data,接着我们从最外层寻找to_repersertation方法。

    3.如何反向生成url?

    字段类型(HyperlinkedIdentityField)就是字段生成url,在上图中,进行第一次to_represention方法是返回的是一个对象。

     

    在HyperlinkedIdentityField类的to_represention最后调用的是django内置的生成url的方法reverse。

    请求数据校验

    urls.py

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

     views.py

    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')])
        
            def validate_user (self,value):
            print(value)
            raise exceptions.ValidationError('拒绝你了!!!!')
    
    class TestView(APIView):
        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请求,响应内容')  

     源码分析

    1.实例化过程

    将data赋值给initial_data

    2.如果实现数据校验?

    ser.is_valid()方法的返回值肯定是个bool值,进一步进入内部,看如何实现校验。

     

      

  • 相关阅读:
    pip安装requests时报 Requirement already satisfied: requests in d:pythonpyth... 的问题解决
    渗透测试靶场
    Spring Security核心类关系图
    Spring security 5 Authorize Configuration
    固定技术栈
    redis 指定端口 启动
    Spring 获取当前activeProfile
    通过进程编号 查询 监听端口
    lombok 插件安装
    idea 快捷键设置
  • 原文地址:https://www.cnblogs.com/kxsph/p/10615912.html
Copyright © 2020-2023  润新知