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("....")

浙公网安备 33010602011771号