Fork me on GitHub

rest_framework 序列化应用之数据验证

#views序列化  可以验证数据 可以自定义验证字段值

class PasswordValidator(object):
    def __init__(self, base):
        self.base = base

    def __call__(self, value):
        """
        用户发送过来的值
        :param value:
        :return:
        """
        if value != 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

from rest_framework import serializers
from rest_framework.serializers import CharField,IntegerField
from rest_framework.response import Response
class UserSerilize(serializers.Serializer):
    user=serializers.CharField(error_messages={'required':'用户名不能为空'})
    password=serializers.CharField(validators=[PasswordValidator("666")]) #自定义验证
    email=serializers.EmailField()
    user_type_id=serializers.IntegerField()
    ug=serializers.CharField(source="ug.title",required=False) #source 代表源 required代表可以不填


class SerilizeView(APIView):
    def get(self, request, *args, **kwargs):
        user_list=UserInfo.objects.all()
        ser=UserSerilize(instance=user_list,many=True)#列表

        # user_obj = UserInfo.objects.all().first()#对象
        # ser = UserSerilize(isinstance=user_obj, many=False)
        # return HttpResponse(ser.data)#把数据库的数据序列化了  这个HttpResponse是django的 UserSerilize是restformwork的 他们兼容不太好
        #OrderedDict([('user', 'morgana'), ('password', '123'), ('email', '123@123'), ('user_type_id', 1)])
        #OrderedDict([('user', 'm1'), ('password', '123'), ('email', '123@123'), ('user_type_id', 2)])
        return Response(ser.data) #http://127.0.0.1:8000/v1/serilize.json?tk=939849a9882fedd26a587465c3f37f9e
        # [
        #     {
        #         "user": "morgana",
        #         "password": "123",
        #         "email": "123@123",
        #         "user_type_id": 1
        #     },
        #     {
        #         "user": "m1",
        #         "password": "123",
        #         "email": "123@123",
        #         "user_type_id": 2
        #     }
        # ]

    def post(self,request,*args,**kwargs):
        ser = UserSerilize(data=request.data)
        if ser.is_valid():
            print(ser.validated_data)
            print(request.data)
            return  Response(ser.validated_data)
        else:
            print(ser.errors)
            return Response(ser.errors)
        # return HttpResponse("....")
urls.py
from django.conf.urls import url
from django.contrib import admin
from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def dispatch(request):
    pass


from app01.views import LoginView,OrderView,IndexView,ParserView,SerilizeView
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^(?P<version>\w+)/auth/$', LoginView.as_view(), name='yyyy'),
    url(r'^(?P<version>\w+)/index/$',IndexView.as_view(),name='xxxx'),
    url(r'^(?P<version>\w+)/order/$', OrderView.as_view(),name='zzzz'),
    url(r'^(?P<version>\w+)/parser/$', ParserView.as_view(),name='aaa'),
    url(r'^(?P<version>\w+)/serilize/$', SerilizeView.as_view(),name='eee'),
    url(r'^(?P<version>\w+)/serilize\.(?P<format>\w+)$', SerilizeView.as_view(),name='eee'),

    # url(r'^test/',csrf_exempt(dispatch)), #不用做csrf_token认证
]

  

基于model自动生成字段版本

from rest_framework.negotiation import DefaultContentNegotiation
from rest_framework.parsers import JSONParser
from rest_framework.parsers import FormParser
class ParserView(APIView):
   parser_classes = [JSONParser,FormParser]
   # content_negotiation_class = "" 根据请求头选择的一般不写
   def get(self,request,*args,**kwargs):
       # print(self.content_negotiation_class) #<class 'rest_framework.negotiation.DefaultContentNegotiation'>
       print(self.parser_classes)
       #[<class 'rest_framework.parsers.JSONParser'>,
       # <class 'rest_framework.parsers.FormParser'>,
       # <class 'rest_framework.parsers.MultiPartParser'>] #既能发送文件 又能传输数据form 表单 文件
       return HttpResponse("....")

   def post(self,request,*args,**kwargs):

       print(request.data) #在使用request.data时调用

       #数据之所以被拿到只因为 数据已经被处理过了
       #找到/usr/local/lib/python3.6/site-packages/rest_framework/request.py---》def data
       #---》self._load_data_and_files()---》def _load_data_and_files--》#调用了self._parse() 方法把文件和内容获取到
       #---》def _parse(self)---》media_type = self.content_type-->def content_type 获取请求头中的content-type
       #return meta.get('CONTENT_TYPE', meta.get('HTTP_CONTENT_TYPE', ''))

       #negotiator laobao
       #media_type 需求
       #self.pasers girls

       #每个girl都有标签 例如JSONParser 只要media_type = 'application/json'
       #FormParser 只负责 media_type = 'application/x-www-form-urlencoded'的
       #/usr/local/lib/python3.6/site-packages/rest_framework/negotiation.py--》class DefaultContentNegotiation
       #---》def select_parser--》for parser in parsers ♻️每个girl 如果匹配就返回parser 不匹配报异常

       # parser = self.negotiator.select_parser(self, self.parsers)  # self.negotiator是在request被实例化后放进来的

       #/usr/local/lib/python3.6/site-packages/rest_framework/views.py
       #def dispatch -->request = self.initialize_request(request, *args, **kwargs)
       #--->parsers=self.get_parsers(),--->return [parser() for parser in self.parser_classes]#定义paster类的对象列表
       #--->negotiator=self.get_content_negotiator(),---->return self._negotiator

       #parser_classes = api_settings.DEFAULT_PARSER_CLASSES
       #content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS

       return HttpResponse ("....")


#序列化  可以验证数据 可以自定义验证字段值

class PasswordValidator(object):
    def __init__(self, base):
        self.base = base

    def __call__(self, value):
        """
        用户发送过来的值
        :param value:
        :return:
        """
        if value != 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

from rest_framework import serializers
from rest_framework.serializers import CharField,IntegerField
from rest_framework.response import Response
class UserSerilize(serializers.ModelSerializer):#😄
    user=serializers.CharField() #可以对字段重写#😄
    ug =serializers.HyperlinkedIdentityField(view_name='ffff') #变成资源链接 view_name是反向生成url的名称
    class Meta:
        model = UserInfo
        fields = "__all__" #可定制字段
        depths=2 #跟它相关联的几级都会显示处理,挎表 大于等于1 小于10 慎用 性能会损耗;ug的title会显示 效果等同于 ug =serializers.CharField(source='ug.title')
    #内部会循环model表里面的所有字段 源码/usr/local/lib/python3.6/site-packages/rest_framework/serializers.py
    #class ModelSerializer--》dict{} serializer_field_mapping


# class UserSerilize(serializers.ModelSerializer):#😄
#     user=serializers.CharField(min_length=6) #可以对字段重写#😄
#     pwd = serializers.CharField(validators=[PasswordValidator("666")])
#     ug =serializers.HyperlinkedIdentityField(view_name='ffff') #变成资源链接 view_name是反向生成url的名称
#     class Meta:
#         model = UserInfo
#         fields = "__all__"
#
# class UserSerilize(serializers.ModelSerializer):#😄
#     user=serializers.CharField()
#     ug =serializers.HyperlinkedIdentityField(view_name='ffff') #变成资源链接 view_name是反向生成url的名称
#     class Meta:
#         model = UserInfo
#         fields = "__all__"
#         extra_kwargs = {
#             'user':{'min_length':6},
#             'pwd':{'validators':[PasswordValidator("666")]}
#         }

 自动生成url

class UserSerilize(serializers.HyperlinkedModelSerializer):#😄 #生成资源链接
    class Meta:
        model = UserInfo
        # fields = "__all__"
        fields = ["user","password",'id','url']
        # Could not resolve URL for hyperlinked relationship using view name "usergroup-detail".You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.



class SerilizeView(APIView):
    def get(self, request, *args, **kwargs):
        user_list=UserInfo.objects.all()
        ser=UserSerilize(instance=user_list,many=True,context={'request':request})#列表 👌context={'request':request}反向生成时资源用的

        # user_obj = UserInfo.objects.all().first()#对象
        # ser = UserSerilize(isinstance=user_obj, many=False)
        # return HttpResponse(ser.data)#把数据库的数据序列化了  这个HttpResponse是django的 UserSerilize是restformwork的 他们兼容不太好
        #OrderedDict([('user', 'morgana'), ('password', '123'), ('email', '123@123'), ('user_type_id', 1)])
        #OrderedDict([('user', 'm1'), ('password', '123'), ('email', '123@123'), ('user_type_id', 2)])
        return Response(ser.data) #http://127.0.0.1:8000/v1/serilize.json?tk=939849a9882fedd26a587465c3f37f9e
        # [
        #     {
        #         "user": "morgana",
        #         "password": "123",
        #         "email": "123@123",
        #         "user_type_id": 1
        #     },
        #     {
        #         "user": "m1",
        #         "password": "123",
        #         "email": "123@123",
        #         "user_type_id": 2
        #     }
        # ]

    def post(self,request,*args,**kwargs):
        ser = UserSerilize(data=request.data)
        if ser.is_valid():
            print(ser.validated_data)
            print(request.data)
            return  Response(ser.validated_data)
        else:
            print(ser.errors)
            return Response(ser.errors)
        # return HttpResponse("....")

  

 

  

posted on 2017-11-24 19:38  vmaze  阅读(224)  评论(0)    收藏  举报

导航