Django Rest Framework(版本、解析器、序列化、数据验证)
<div id="cnblogs_post_body" class="blogpost-body"> 一、版本程序也来越大时,可能通过版本不同做不同的处理 没用rest_framework之前,我们可以通过以下这样的方式去获取。 get(self,request,*args,** version = request.query_params.get( version==
ret = :111 :
version==
ret = : 112 :
ret = :
Response(ret)
现在我们来用rest_framework实现一下 a. 基于url的get传参方式如:/users?version=v1 REST_FRAMEWORK =: ,
: [,],
:
}
django.conf.urls web.views urlpatterns =<span style="color: #000000;"> [
url(r<span style="color: #800000;">'<span style="color: #800000;">^test/<span style="color: #800000;">',TestView.as_view(),name=<span style="color: #800000;">'<span style="color: #800000;">test<span style="color: #800000;">'<span style="color: #000000;">),]
rest_framework.views rest_framework.response rest_framework.versioning <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
versioning_class =<span style="color: #000000;"> QueryParameterVersioning
b. 基于url的正则方式如:/v1/users/ REST_FRAMEWORK =: ,
:
}
django.conf.urls web.views urlpatterns =<span style="color: #000000;"> [
url(r<span style="color: #800000;">'<span style="color: #800000;">^(?P
rest_framework.views rest_framework.response rest_framework.versioning <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
versioning_class =<span style="color: #000000;"> URLPathVersioning
c. 基于accept 请求头方式如:Accept: application/json; version=1.0 REST_FRAMEWORK =: ,
:
}
django.conf.urls
rest_framework.views rest_framework.response rest_framework.versioning <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
versioning_class =<span style="color: #000000;"> AcceptHeaderVersioning
d. 基于主机名方法如:v1.example.com ALLOWED_HOSTS = [=: ,
:
}
django.conf.urls
rest_framework.views rest_framework.response rest_framework.versioning <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
versioning_class =<span style="color: #000000;"> HostNameVersioning
<div class="cnblogs_code" onclick="cnblogs_code_show('c8d351b2-3a89-442f-8af5-5996311a9bb9')"> <div id="cnblogs_code_open_c8d351b2-3a89-442f-8af5-5996311a9bb9" class="cnblogs_code_hide">
urlpatterns =
url(r,include(
<span style="color: #000000;">
如果遇到这样的错误
ALLOWED_HOSTS = []
e. 基于django路由系统的namespace如:example.com/v1/users/ REST_FRAMEWORK =: ,
:
}
django.conf.urls web.views urlpatterns =<span style="color: #000000;"> [
url(r<span style="color: #800000;">'<span style="color: #800000;">^v1/<span style="color: #800000;">'<span style="color: #000000;">,([ url(r<span style="color: #800000;">'<span style="color: #800000;">test/<span style="color: #800000;">',],None,<span style="color: #800000;">'<span style="color: #800000;">v1<span style="color: #800000;">'<span style="color: #000000;">)),url(r<span style="color: #800000;">'<span style="color: #800000;">^v2/<span style="color: #800000;">'<span style="color: #000000;">,<span style="color: #800000;">'<span style="color: #800000;">v2<span style="color: #800000;">'<span style="color: #000000;">)),]
rest_framework.views rest_framework.response rest_framework.versioning <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
versioning_class =<span style="color: #000000;"> NamespaceVersioning
#http://127.0.0.1:8080/api/v1/users/
urlpatterns =[v1|v2]+)/,]
<span style="color: #008000;">#<span style="color: #008000;">api.urls.py
urlpatterns =<span style="color: #000000;"> [ url(r<span style="color: #800000;">'<span style="color: #800000;">^users/<span style="color: #800000;">',views.UserView1.as_view(),name=<span style="color: #800000;">'<span style="color: #800000;">users-list<span style="color: #800000;">'<span style="color: #000000;">),] <span style="color: #008000;">#<span style="color: #008000;">views.py <span style="color: #000000;">导入类 <span style="color: #0000ff;">from rest_framework.reverse <span style="color: #0000ff;">import<span style="color: #000000;"> reverse url = request.versioning_scheme.reverse(viewname=<span style="color: #800000;">'<span style="color: #800000;">users-list<span style="color: #800000;">',request=<span style="color: #000000;">request) <span style="color: #0000ff;">print(url) 我们自己用django实现的,当前版本不一样的时候可以用这种方式 django.urls = reverse(viewname=,kwargs={:})
(url)
f. 全局使用REST_FRAMEWORK =:: : [,:
注:在配置的时候 REST_FRAMEWORK =: #如果加上这个配置就不用versioning_class = QueryParameterVersioning这样再指定了,
:
<h1 class="title">二、解析器(parser):reqest.data取值的时候才执行 对请求的数据进行解析:是针对请求体进行解析的。表示服务器可以解析的数据格式的种类 django中的发送请求
Content-Type: application/url-<span style="color: #008000;">#<span style="color: #008000;">如果是发送的json的格式,在POST里面是没有值的,在body里面有值,可通过decode,然后loads取值
Content-Type: application/<span style="color: #000000;">json..... request.body request.POST 为了这种情况下每次都要decode,loads,显得麻烦,所以才有的解析器。弥补了django的缺点 Content-Type: application/
读取客户端发送的Content-Type的值 application/
parser_classes = [JSONParser,FormParser]
media_type_list = [,
如果客户端的Content-Type的值和 application/ 如果客户端的Content-Type的值和 application/x-www-form-
parser_classes =
REST_FRAMEWORK = : : :[,
:
get(self,** Response( post(self,** (request.data)
Response()
根据请求头 content-type 选择对应的解析器就请求体内容进行处理。 a. 仅处理请求头content-type为application/json的请求体 django.conf.urls web.views.s5_parser urlpatterns =<span style="color: #000000;"> [
url(r<span style="color: #800000;">'<span style="color: #800000;">test/<span style="color: #800000;">',]
rest_framework.views rest_framework.response rest_framework.request rest_framework.parsers <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
parser_classes =<span style="color: #000000;"> [JSONParser,]
b.仅处理请求头content-type为application/x-www-form-urlencoded的请求体 django.conf.urls web.views urlpatterns =<span style="color: #000000;"> [
url(r<span style="color: #800000;">'<span style="color: #800000;">test/<span style="color: #800000;">',]
rest_framework.views rest_framework.response rest_framework.request rest_framework.parsers <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
parser_classes =<span style="color: #000000;"> [FormParser,**<span style="color: #000000;">kwargs): <span style="color: #0000ff;">return Response(<span style="color: #800000;">'<span style="color: #800000;">PUT请求,响应内容<span style="color: #800000;">') c.仅处理请求头content-type为multipart/form-data的请求体 django.conf.urls
rest_framework.views rest_framework.response rest_framework.request rest_framework.parsers <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
parser_classes =<span style="color: #000000;"> [MultiPartParser,**<span style="color: #000000;">kwargs): <span style="color: #0000ff;">print<span style="color: #000000;">(request.content_type)
>
>
d. 仅上传文件 django.conf.urls web.views
urlpatterns = url(r[^/]+), ]
rest_framework.views rest_framework.response rest_framework.request rest_framework.parsers
parser_classes =
post(self,filename,**
Response(
put(self,** Response()
>
>
e. 同时多个Parser当同时使用多个parser时,rest framework会根据请求头content-type自动进行比对,并使用对应parser django.conf.urls
rest_framework.views rest_framework.response rest_framework.request rest_framework.parsers <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
parser_classes =<span style="color: #000000;"> [JSONParser,MultiPartParser,**<span style="color: #000000;">kwargs): <span style="color: #0000ff;">return Response(<span style="color: #800000;">'<span style="color: #800000;">PUT请求,响应内容<span style="color: #800000;">') f.全局使用REST_FRAMEWORK =
}
django.conf.urls
rest_framework.views rest_framework.response <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
<span style="color: #0000ff;">def post(self,**<span style="color: #000000;">kwargs): <span style="color: #0000ff;">return Response(<span style="color: #800000;">'<span style="color: #800000;">PUT请求,响应内容<span style="color: #800000;">') request.data取POST的值 注意:个别特殊的值可以通过Django的request对象 request._request 来进行获取 获取get的数据,可以通过request._request.GET或者request.query_params或request.GET 因为 <div class="cnblogs_code" onclick="cnblogs_code_show('5d2e387b-236c-4b61-bdfa-8b780f067cb2')"> <div id="cnblogs_code_open_5d2e387b-236c-4b61-bdfa-8b780f067cb2" class="cnblogs_code_hide"> dispatch(self,**==
request = self.initialize_request(request,**= request
(self,parsers=None,authenticators==None,parser_context=
.,request..
self._request </span>= request <span style="color: #008000;">#</span><span style="color: #008000;">将django中的request对象封装到了_request中</span></pre>
getattr(self._request,attr)
self.(attr)
<h1 id="lable3" class="title">三、序列化 序列化用于对用户请求数据进行验证和数据进行序列化(为了解决queryset序列化问题)。 那什么是序列化呢?序列化就是把对象转换成字符串,反序列化就是把字符串转换成对象 <p class="secondtitle">a. 自定义字段 <div class="cnblogs_code" onclick="cnblogs_code_show('e5624de1-596d-43b9-8998-b8788167d828')"> <div id="cnblogs_code_open_e5624de1-596d-43b9-8998-b8788167d828" class="cnblogs_code_hide"> django.conf.urls web.views.s6_serializers urlpatterns =<span style="color: #000000;"> [
rest_framework.views rest_framework.response rest_framework .. <span style="color: #0000ff;">class<span style="color: #000000;"> PasswordValidator(object):
<span style="color: #0000ff;">def <span style="color: #800080;">init<span style="color: #000000;">(self,base): self.base =<span style="color: #000000;"> base
<span style="color: #0000ff;">class <span style="color: #000000;"> UserSerializer(serializers.Serializer):ut_title = serializers.CharField(source=<span style="color: #800000;">'<span style="color: #800000;">ut.title<span style="color: #800000;">'<span style="color: #000000;">) user = serializers.CharField(min_length=6<span style="color: #000000;">) pwd = serializers.CharField(error_messages={<span style="color: #800000;">'<span style="color: #800000;">required<span style="color: #800000;">': <span style="color: #800000;">'<span style="color: #800000;">密码不能为空<span style="color: #800000;">'},validators=[PasswordValidator(<span style="color: #800000;">'<span style="color: #800000;">666<span style="color: #800000;">'<span style="color: #000000;">)]) <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
b. 基于Model自动生成字段 django.conf.urls
rest_framework.views rest_framework.response rest_framework .. <span style="color: #0000ff;">class<span style="color: #000000;"> PasswordValidator(object):
<span style="color: #0000ff;">def <span style="color: #800080;">init<span style="color: #000000;">(self,base): self.base =<span style="color: #000000;"> str(base)
<span style="color: #0000ff;">class <span style="color: #000000;"> ModelUserSerializer(serializers.ModelSerializer):
<span style="color: #0000ff;">class <span style="color: #000000;"> TestView(APIView):<span style="color: #0000ff;">def get(self,**<span style="color: #000000;">kwargs):
c. 生成URL django.conf.urls d+)/,name=
rest_framework.views rest_framework.response rest_framework .. <span style="color: #0000ff;">class<span style="color: #000000;"> PasswordValidator(object):
<span style="color: #0000ff;">def <span style="color: #800080;">init<span style="color: #000000;">(self,serializer_fields是当前字段对象 <span style="color: #0000ff;">pass <span style="color: #0000ff;">class <span style="color: #000000;"> ModelUserSerializer(serializers.ModelSerializer):ut = serializers.HyperlinkedIdentityField(view_name=<span style="color: #800000;">'<span style="color: #800000;">detail<span style="color: #800000;">'<span style="color: #000000;">) <span style="color: #0000ff;">class<span style="color: #000000;"> Meta: model =<span style="color: #000000;"> models.UserInfo fields = <span style="color: #800000;">"<span style="color: #800000;">all<span style="color: #800000;">"<span style="color: #000000;">
<span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
d. 自动生成URL django.conf.urls
rest_framework.views rest_framework.response rest_framework .. <span style="color: #0000ff;">class<span style="color: #000000;"> PasswordValidator(object):
<span style="color: #0000ff;">def <span style="color: #800080;">init<span style="color: #000000;">(self,serializer_fields是当前字段对象 <span style="color: #0000ff;">pass <span style="color: #0000ff;">class <span style="color: #000000;"> ModelUserSerializer(serializers.HyperlinkedModelSerializer):ll = serializers.HyperlinkedIdentityField(view_name=<span style="color: #800000;">'<span style="color: #800000;">xxxx<span style="color: #800000;">'<span style="color: #000000;">) tt = serializers.CharField(required=<span style="color: #000000;">False)
<span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):<span style="color: #0000ff;">def get(self,<span style="color: #000000;">kwargs): <span style="color: #008000;">#<span style="color: #008000;"> # 序列化,将数据库查询字段序列化为字典 data_list =<span style="color: #000000;"> models.UserInfo.objects.all() ser = ModelUserSerializer(instance=data_list,context={<span style="color: #800000;">'<span style="color: #800000;">request<span style="color: #800000;">'<span style="color: #000000;">: request}) <span style="color: #008000;">#<span style="color: #008000;"> # 如果Many=True <span style="color: #008000;">#<span style="color: #008000;"> # 或 <span style="color: #008000;">#<span style="color: #008000;"> # obj = models.UserInfo.objects.all().first() <span style="color: #008000;">#<span style="color: #008000;"> # ser = UserSerializer(instance=obj,<span style="color: #000000;">kwargs): <span style="color: #008000;">#<span style="color: #008000;"> 验证,对请求发来的数据进行验证 <span style="color: #0000ff;">print<span style="color: #000000;">(request.data) ser = ModelUserSerializer(data=<span style="color: #000000;">request.data) <span style="color: #0000ff;">if<span style="color: #000000;"> ser.is_valid(): <span style="color: #0000ff;">print<span style="color: #000000;">(ser.validated_data) <span style="color: #0000ff;">else<span style="color: #000000;">: <span style="color: #0000ff;">print<span style="color: #000000;">(ser.errors)
<h2 class="secondtitle">1、基本操作 <div id="cnblogs_code_open_9ac5e44c-4c0c-4a38-abb5-166b39368ee8" class="cnblogs_code_hide"> django.db <span style="color: #008000;">#<span style="color: #008000;"> Create your models here.<span style="color: #000000;"> Group(models.Model): title = models.CharField(max_length=32<span style="color: #000000;">) mu = models.ForeignKey(to=<span style="color: #800000;">'<span style="color: #800000;">Menu<span style="color: #800000;">',default=1<span style="color: #000000;">) <span style="color: #0000ff;">class<span style="color: #000000;"> UserInfo(models.Model):
<span style="color: #0000ff;">class<span style="color: #000000;"> Menu(models.Model): <span style="color: #0000ff;">class<span style="color: #000000;"> Role(models.Model): <div class="cnblogs_code" onclick="cnblogs_code_show('2921de3f-601d-4995-8679-14a8261f74cf')"> <div id="cnblogs_code_open_2921de3f-601d-4995-8679-14a8261f74cf" class="cnblogs_code_hide"> django.shortcuts rest_framework.views rest_framework.response rest_framework.versioning rest_framework.versioning QueryParameterVersioning
rest_framework.versioning URLPathVersioning
rest_framework.versioning rest_framework.parsers JSONParser
rest_framework app03 name = serializers.CharField()
pwd =
get(self,**
user = ser = UsersSerializer(instance=user,many=
Response(ser.data)
x1 = serializers.CharField(source=)
如果你想跨表拿你任何需要的数据,都可以用上面的这种操作,内部做判断,如果可用内部就加括号调用了 rest_framework.views rest_framework.response rest_framework app03 name = serializers.CharField()
pwd =
x1 = serializers.CharField(source= roles = serializers.CharField(source=)
get(self,**
user = ser = UsersSerializer(instance=user,many=
Response(ser.data)
自定义类和方法 解决方案一:
to_representation(self,value):
data_list = row
name = serializers.CharField()
pwd = serializers.CharField()
group_id = serializers.CharField()
xxxx = serializers.CharField(source=)
x1 = serializers.CharField(source=)
x2 = MyCharField(source=)
解决方案二: {:value.pk,
name = serializers.CharField()
pwd = serializers.CharField()
group_id = serializers.CharField()
xxxx = serializers.CharField(source=)
x1 = serializers.CharField(source=)
x2 = serializers.ListField(child=MyCharField(),source=)
解决方案三(推荐使用) name = serializers.CharField()
pwd = serializers.CharField()
group_id = serializers.CharField()
xxxx = serializers.CharField(source=)
x1 = serializers.CharField(source=)
x2 =
get_x2(self,obj):
(obj)
role_list = obj.roles.filter(id__gt=1 data_list = row data_list.append({:row.pk,
= serializers.CharField(source== serializers.HyperlinkedIdentityField(view_name=
model </span>=<span style="color: #000000;"> models.UserInfo
</span><span style="color: #008000;">#</span><span style="color: #008000;"> fields = "__all__"</span>
fields = [<span style="color: #800000;">'</span><span style="color: #800000;">name</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">pwd</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">group</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">x1</span><span style="color: #800000;">'</span>] <span style="color: #008000;">#</span><span style="color: #008000;">自定义字段的时候注意要指定source,scource里面的数据必须是数据库有的数据</span>
depth = 1 <span style="color: #008000;">#</span><span style="color: #008000;">表示深度</span>
<span style="color: #0000ff;">class <span style="color: #000000;"> UsersView(APIView):<span style="color: #0000ff;">def get(self,**<span style="color: #000000;">kwargs): self.dispatch <span style="color: #008000;">#<span style="color: #008000;"> 方式一: <span style="color: #008000;">#<span style="color: #008000;"> user_list = models.UserInfo.objects.all().values('name','groupid',"grouptitle") <span style="color: #008000;">#<span style="color: #008000;"> return Response(user_list)
=
</span></span><span style="color: #0000ff;">class</span><span style="color: #000000;"> Meta:
model </span>=<span style="color: #000000;"> models.Article
fields </span>= [<span style="color: #800000;">'</span><span style="color: #800000;">title</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">source</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">brief</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">view_num</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">comment_num</span><span style="color: #800000;">'</span><span style="color: #000000;">,</span><span style="color: #800000;">'</span><span style="color: #800000;">collect_num</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">published_time</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">head_img</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">content</span><span style="color: #800000;">'</span>,<span style="color: #800000;">'</span><span style="color: #800000;">agree_num</span><span style="color: #800000;">'</span><span style="color: #000000;">] <span style="color: #008000;"># 将自定义的字段放到fields中,通过fields='__all__'也可以
depth = 1 <span style="color: #008000;">#<span style="color: #008000;"> 表示深度
<h2 class="secondtitle">5、指定生成URL <div id="cnblogs_code_open_f9318372-7b65-48b4-9a34-82e9f64dd158" class="cnblogs_code_hide"> UsersSerializer(serializers.ModelSerializer): group = serializers.HyperlinkedIdentityField(view_name=)
==
depth = 1
django.conf.urls django.contrib app03 =
url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^users4/</span><span style="color: #800000;">'</span>,views.UserView4.as_view(),name=<span style="color: #800000;">'</span><span style="color: #800000;">xxx</span><span style="color: #800000;">'</span><span style="color: #000000;">),url(r</span><span style="color: #800000;">'</span><span style="color: #800000;">^users5/(?P<pk>.*)</span><span style="color: #800000;">'</span>,views.UserView5.as_view(),name=<span style="color: #800000;">'</span><span style="color: #800000;">detail</span><span style="color: #800000;">'</span>),<span style="color: #008000;">#</span><span style="color: #008000;">必须叫pk</span>
]
UsersSerializer(serializers.HyperlinkedModelSerializer):
model = fields =
get(self,**
user_list =
ser = UsersSerializer(instance=user_list,context={ Response(ser.data)
self.base =
value != message = %
name = serializers.CharField(min_length=6 pwd = serializers.CharField(error_messages={: },validators=[PasswordValidator()])
model = fields =
extra_kwargs = : {: 6 : {: [PasswordValidator(666 }
使用 get(self,**
user_list =
ser = UsersSerializer(instance=user_list,context={
post(self,** ser = UsersSerializer(data= Response()
钩子函数 ValidationError(detail=
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |