序列化-请求数据校验。。。。。。

序列化

拿到所有的角色数据

1.urls.py

2.models.py  假设只有3个角色

3.views.py

from api import models

import json

json只能序列化python的基本数据类型!!!!

QueryDict是django定义的类!!!!

所以以下这种操作会报错!!!

4.解决方案:取某个字段,然后转成list数据,再转成json数据。

返回数据:注意汉字都变成字节码了!!!

5.显示中文  ensure_ascii=False

  1. json序列化方法

ret = json.dumps(ser.data, ensure_ascii=False)

运行结果:

方式一:Serializer

1.from rest_framework import serializers

serializers.Serializer

  1. from rest_framework import serializers
  2. class RolesSerializers(serializers.Serializer):
  3. title = serializers.CharField()

2.

3.

4.运行结果

5.title是固定的吗???能不能随便写,比如ttt

运行结果:

注意:必须和数据库的字段一致才行,不能随便写。否则会报错。

普通字段

6.也有id字段,数字类型。

运行结果:

7.对单个对象序列化

代码:

urls.py
url(r‘^(?P<version>[v1|v2]+)/roles/$‘, views.RolesView.as_view()),
views.py
from  rest_framework import serializers
class RolesSerializers(serializers.Serializer):
    id = serializers.IntegerField()
    title = serializers.CharField()
class RolesView(APIView):
    def get(self, request, *args, **kwargs):
        roles = models.Role.objects.all().first()
        ser = RolesSerializers(instance=roles, many=False)
        # ser.data 已经是转换完成的结果
        ret = json.dumps(ser.data, ensure_ascii=False)
        # {"id": 1, "title": "医生"}
        return HttpResponse(ret)

1.urls.py

2.models.py  表结构

分组表数据

用户表数据,进行分组,都是A组

3.views.py  查看set.data

打印结果:ser.data 是OrdereDict类型。json能解析该类型的数据。

4.

运行结果:

choices 字段

5.如果要显示用户类型怎么办??? usert_py 下拉框

views.py

显示数字

运行结果:用户类型显示的是数字。

6. source=‘指定对应数据库字段‘。  usert_type这个字段也可以用xxx 表示

运行结果:

如何让分组显示中文汉字呢???

7.序列化某个字段,字段写了source.  取得user_type这个值,在源码 会自动判断该字段是否能被调用。能则字段加括号调用,如果不能则页面之间显示结果。

比如user_type字段是数字不能调用,则返回数字。

row.get_user_type_display  该字段可被调用。会自动加括号,帮我们去执行。

view.py

运行结果:显示中文汉字!!!

8.接下来,显示分组。group字段 1对多

views.py

运行结果:gp是一个对象

一对多字段

9.如果想去分组的id怎么办???group.id

也可以group.title  显示title组名

运行结果:

多对多字段

10.接下来,取当前用户喜欢的所有角色   多对多的关系

用户——角色 关系表       添加数据

views.py

运行结果:

自定义函数:用于某些字段用source取不到的情况

11.多对多字段 用source做不到特别细的粒度,所有用另一种方式:自定义函数。

views.py  自定义函数:返回一个[]

运行结果:

12.显示一个列表[ {},{} ]  的类型

运行结果:显示一个列表[ {},{} ]

13.以上数据写死了,我们需要动态获取。

获取所有对象,遍历

运行结果:

方式二:ModelSerializer

1.继承的类  serializers.ModelSerializer

2.看源码: ModelSerializer 继承了 Serializer类

3.字段不用自己写了

4.运行结果:数据全都自动生成了。但是只能完成基本的数据

5.如果想要进一步拿数据,就需要自己定义了

运行结果:

6.choices 类型字段  显示中文

运行结果:

7.多对多字段  自定义函数

运行结果:

8.自定义 一个字段

1.

2.

3.功能是一样的

4.x1字段 自定义返回结果:xxxxx

运行结果:

打印结果:value: username字段对应的值

自动序列化连表  depth = 1

# 1取中文 0取id 0 ~ 10  多对多、一对多都会自动取值。

1.原数据

运行结果:

2.字段想要中文怎么办?????

  1. depth = 1 # 1取中文 0取id 0 ~ 10 多对多、一对多都会自动取值。

运行结果:

3.depth = 0

4.fields也适用

运行结果:

生成链接

1.

2.id生成url

urls.py    起别名,通过别名反向生成url

views.py   分组视图

3.userinfo视图

  1. HyperlinkedIdentityField 默认生成url
  1. group = serializers.HyperlinkedIdentityField(view_name=‘gp‘)

运行结果:

4.分组视图 还需要再加上一个参数。

运行结果:   我们只有一个组,但是后面的数字不对应!!!

5.我们只有一个组,但是后面的数字不对应!!!  数据有问题怎么办呢???

6.(?P<xxx>)分组别名改了 xxx

urls.py

views.py

  1. group = serializers.HyperlinkedIdentityField(view_name=‘gp‘,lookup_field=‘group_id‘,lookup_url_kwarg=‘pk‘)

运行结果: 数据对应了

8. 分组视图  (?P<xxx>)

9.查看分组详细

代码:

url(r‘^(?P<version>[v1|v2]+)/group(?P<pk>\d+)/$‘, views.GroupView.as_view(),name=‘gp‘),
from  rest_framework import serializers
# class UserInfoSerializers(serializers.Serializer):
class UserInfoSerializers(serializers.ModelSerializer):
    # 根据分组id反向生产url
    group = serializers.HyperlinkedIdentityField(view_name=‘gp‘,lookup_field=‘group_id‘,lookup_url_kwarg=‘pk‘)
    class Meta:
        model = models.UserInfo
        fields = [‘id‘,‘username‘,‘password‘,‘group‘]
        depth = 1  # 1取中文 0取id  0 ~ 10

class UserinfoView(APIView):
    def get(self, request, *args, **kwargs):
        users = models.UserInfo.objects.all()
        # 1.实例化,一般是将数据封装到对象:__new__,__init__
        # 一个对象, Serializer类处理; self.to_representation
        # QuerySet集合,ListSerializer类处理; self.to_representation
        set = UserInfoSerializers(instance=users, many=True,context={‘request‘: request})
        set.data
        ret = json.dumps(set.data, ensure_ascii=False)
        return HttpResponse(ret)
# 序列化数据分组
class GroupSerializers(serializers.ModelSerializer):
    class Meta:
        model = models.UserGroup
        fields = "__all__"

# 把id换成路由。
class GroupView(APIView):
    def get(self, request, *args, **kwargs):
        pk = kwargs.get(‘pk‘)
        obj = models.UserGroup.objects.filter(pk=pk).first()
        ser = GroupSerializers(instance=obj,many=False)  # 单个对象
        ret = json.dumps(ser.data,ensure_ascii=False)  # 中文
        return HttpResponse(ret)

序列化源码流程:ModelSerializer

0.from rest_framework import serializers

1.创建类,2.实例化类

代码:

from  rest_framework import serializers
# class UserInfoSerializers(serializers.Serializer):
class UserInfoSerializers(serializers.ModelSerializer):
    # 根据分组id反向生产url
    group = serializers.HyperlinkedIdentityField(view_name=‘gp‘,lookup_field=‘group_id‘,lookup_url_kwarg=‘pk‘)
    class Meta:
        model = models.UserInfo
        fields = [‘id‘,‘username‘,‘password‘,‘group‘]
        depth = 1  # 1取中文 0取id  0 ~ 10

class UserinfoView(APIView):
    def get(self, request, *args, **kwargs):
        users = models.UserInfo.objects.all()
        # 1.实例化,一般是将数据封装到对象:__new__,__init__
        set = UserInfoSerializers(instance=users, many=True,context={‘request‘: request})
        ret = json.dumps(set.data, ensure_ascii=False)
        return HttpResponse(ret)

3.类在实例化之前会执行什么方法???

python 当一个类实例化的时候先会执行构造方法__init__,其实在构造方法之前会先执行__new__方法.

自定义类下没有new 和init方法,接下去继承类里找。

4.

5.ModelSerializer 也没有没有new 和init方法,接下去继承类里找。

6.Serializer 还是没有没有new 和init方法,接下去继承类里找。

  1. BaseSerializer 类里面有new 和init方法

7.

8.在new方法做了区分处理。  QuerySet实际处理它的类是 ListSerializer类

9.接下来看 set.data 做了什么事???

点data 继续往下走

10. to_representation

视图加注释

11. 继续往下走,应该抛异常, 但是程序没有抛异常,说明找错了。

12. to_representation 应该先从自定义类开始找。类里面没有该方法,继续往下走

13. ModelSerializer 没有 to_representation

14.  Serializer  有 to_representation

15.

16. 方便查看  get_attribute 方法 做了什么事???

17. 看字段里面有没有  get_attribute 方法。 没有去父类找

18. Field 有 get_attribute 方法。

19.

20.

21.加注释

22.

23.

24.

判断是否是函数类型,2种方法。

请求数据校验:

运行结果:传值了

打印结果:

运行结果:没有传值了

打印结果: 接收值为空

1.那么问题来了: 对数据进行校验,假设不允许值为空!!!该怎么办呢???

运行结果:

没有传值后的打印结果

2.自定义提示信息

打印结果:

title有值

打印结果:

只拿值

打印结果

3.自定义验证规则   假设你写的规则必须以666开头

运行结果:

打印结果:

代码:

############################ 验证##########################
# 自定义验证规则
class xxxValidator(object):
    def __init__(self, base):
        self.base = base
    def __call__(self, value): # 数据一提交 就会执行__call__方法。
        if not value.startswith(self.base):
            message = ‘标题必须以 %s开头!‘ % self.base
            raise serializers.ValidationError(message)
    def set_context(self, serializer_field):
        # 执行验证之前调用,serializer_fields是当前字段对象
        pass

# 序列化数据
class UsergroupSerializers(serializers.Serializer):
    # title = serializers.CharField(error_messages={‘required‘:‘标题不能为空!‘})
    # 写的标题必须也什么开头。
    title = serializers.CharField(error_messages={‘required‘:‘标题不能为空!‘},validators=[xxxValidator(‘老男人‘),])
# 验证用户请求数据
class UsergroupView(APIView):
    def post(self, request, *args, **kwargs):
        ser = UsergroupSerializers(data=request.data)
        if ser.is_valid():
            print(ser.validated_data[‘title‘])
        else:
            print(ser.errors)
        return HttpResponse(‘提交数据‘)

总结:

 序列化:
            部分总结:
                1. 写类
                    class RolesSerializer(serializers.Serializer):
                        id = serializers.IntegerField()
                        title = serializers.CharField()

                    class UserInfoSerializer(serializers.ModelSerializer):
                        class Meta:
                            model = models.UserInfo
                            # fields = "__all__"
                            fields = [‘id‘,‘username‘,‘password‘,]

                2. 字段
                    a. title = serializers.CharField(source="xxx.xxx.xx.xx")
                    b. title = serializers.SerializerMethodField()
                       class UserInfoSerializer(serializers.ModelSerializer):
                            rls = serializers.SerializerMethodField()  # 自定义显示

                            class Meta:
                                model = models.UserInfo
                                fields = [‘id‘,‘username‘,‘password‘,‘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
                    c. 自定义类
                        fields = [‘id‘,‘username‘,‘password‘,‘group‘]
                        depth = 1  # 1取中文 0取id  0 ~ 10

                3. 自动序列化连表
                    class UserInfoSerializer(serializers.ModelSerializer):
                    class Meta:
                        model = models.UserInfo
                        # fields = "__all__"
                        fields = [‘id‘,‘username‘,‘password‘,‘group‘,‘roles‘]
                        depth = 1 # 0 ~ 10

                4. 生成链接
                    class UserInfoSerializer(serializers.ModelSerializer):
                        group = serializers.HyperlinkedIdentityField(view_name=‘gp‘,lookup_field=‘group_id‘,lookup_url_kwarg=‘xxx‘)
                        class Meta:
                            model = models.UserInfo
                            # fields = "__all__"
                            fields = [‘id‘,‘username‘,‘password‘,‘group‘,‘roles‘]
                            depth = 0 # 0 ~ 10

                    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)
            源码:
                一个对象, Serializer类处理;
                QuerySet集合,ListSerializer类处理;
                # ser.data

        请求数据校验:

                class XXValidator(object):
                    def __init__(self, base):
                        self.base = base
                    def __call__(self, value):
                        if not value.startswith(self.base):
                            message = ‘标题必须以 %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 UserGroupSerializer(serializers.Serializer):
                    title = serializers.CharField(error_messages={‘required‘:‘标题不能为空‘},validators=[XXValidator(‘老男人‘),])
                class UserGroupView(APIView):
                    def post(self,request,*args,**kwargs):
                        ser = UserGroupSerializer(data=request.data)
                        if ser.is_valid():
                            print(ser.validated_data[‘title‘])
                        else:
                            print(ser.errors)
                        return HttpResponse(‘提交数据‘)

原文地址:https://www.cnblogs.com/ls13691357174/p/9879744.html

时间: 2024-11-12 08:21:20

序列化-请求数据校验。。。。。。的相关文章

68 drf 响应类reponse 序列化数据校验与写入

1.内部类 就是当前类的配置类 1.序列化组件的配置类 2.数据库model配置类 解释: 伪代码         继承的model类支持db_name,所以Meta类要使用db_name的写法 """ class Car(Model): name = CharFields() class Meta: db_name = "表名" # Car表,将会name作为Car表的字段 (内部可以通过Car.name访问到name) (内部可以通过Car.Meta.

Django Restful Framework【第四篇】版本、解析器、序列化和请求数据验证

一.版本 程序也来越大时,可能通过版本不同做不同的处理 没用rest_framework之前,我们可以通过以下这样的方式去获取. class UserView(APIView): def get(self,request,*args,**kwargs): version = request.query_params.get('version') print(version) if version=='v1': #如果版本是v1 ret = { 'code':111, 'msg':'版本一的内容'

jQuery基础(Ajax,load(),getJSON(),getScript(),post(),ajax(),同步/异步请求数据)

1.使用load()方法异步请求数据 使用load()方法通过Ajax请求加载服务器中的数据,并把返回的数据放置到指定的元素中,它的调用格式为: load(url,[data],[callback]) 参数url为加载服务器地址,可选项data参数为请求时发送的数据,callback参数为数据请求成功后,执行的回调函数. 2.使用getJSON()方法异步加载JSON格式数据 使用getJSON()方法可以通过Ajax异步请求的方式,获取服务器中的数据,并对获取的数据进行解析,显示在页面中,它的

SpringMVC框架下数据的增删改查,数据类型转换,数据格式化,数据校验,错误输入的消息回显

在eclipse中javaEE环境下: 这儿并没有连接数据库,而是将数据存放在map集合中: 将各种架包导入lib下... web.xml文件配置为 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/

在使用Linq to SQL并序列化一个数据对象的时候报System.InvalidOperationException异常,序列化类型XXX的对象时检测到循环引用。

在使用Linq to SQL并序列化一个数据对象的时候报System.InvalidOperationException异常,序列化类型 的对象时检测到循环引用. 异常信息(部分): System.Web.Services.Protocols.SoapException: 服务器无法处理请求. ---> System.InvalidOperationException: 生成 XML 文档时出错. ---> System.InvalidOperationException: 序列化类型 Web

Struts2之数据校验

时间:2017-1-11 11:09 --Struts2提供的数据校验 在开发中,请求参数是需要校验的:    客户端:过滤正常用户的错误操作,通过JS代码完成    服务器:Java代码 Struts2提供的校验是服务器端校验. 校验方式分为两种:    1.手动校验(编码校验)    2.配置校验(自动校验,基于Annotation,基于XML) 1.手动校验:    要求:Action类必须继承ActionSupport,需要重写validate()方法(是Validateable接口中的

Struts2请求参数校验

校验的分类 客户端数据校验 和 服务器端数据校验 客户端数据校验 ,通过JavaScript 完成校验 (改善用户体验,使用户减少出错 ) 服务器数据校验 ,通过Java代码 完成校验 struts2 支持校验方式 代码校验(用的很少) :在服务器端通过编写java代码,完成数据校验 配置校验(主流):XML配置校验(主流) 和 注解配置校验 代码校验请求参数 步骤一: 封装数据 步骤二: 实现校验Action ,必须继承ActionSupport 类 步骤三: 覆盖validate方法(val

Struts2(五)数据校验

一.概述 在提交表单数据时,如果数据需要保存到数据库,空输入等可能会引发一些异常,为了避免引起用户的输入引起底层异常,通常在进行业务逻辑操作之前,先执行基本的数据校验. 下面通过两种方式来阐述Struts 2的数据校验功能. 二.重写validate方法 我们编写的Action一般继承与ActionSupport,而ActionSupport不仅实现了Action接口,还实现了Validatable接口,提供了数据校验功能.在Validatable接口中定义一个validate方法,重写该方法,

mysql数据校验之字符集问题

场景:主库DB:utf8字符集备库DB:gbk字符集 需求:校验主备数据是否一致,并且修复 校验过程:设置主库连接为utf8,设置备库连接为gbk,分别进行查询,将返回的的结果集按记录逐字段比较. 显示结果:原本相同的汉字字符,数据校验认为不一致. 原因分析:对于主库而已,由于建立连接的字符集为UTF8,则返回的汉字字符编码为UTF8格式:对于备库而言则是GBK格式,而程序中通过字符串比较函数strcasecmp进行比较,显然不同的字符集编码,相同的字符有不同的二进制,因此结果肯定不会相等. 进