1 版本
通过?后面传版本号有两种方法:
方法一
from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.authentication import BasicAuthentication from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning,HostNameVersioning from rest_framework.renderers import BrowsableAPIRenderer,JSONRenderer # Create your views here. class UserView(APIView): #版本号通过?后面传参数 def get(self,request,*args,**kwargs): print('11111',request.version) version=request.query_params.get('version') if version=="v1": ret={ "name":"Frank" } elif version=="v2": ret={ "name":"Tom" } else: ret='错误信息' return Response(ret)
方法二:
versioning_class = QueryParameterVersioning#用这个的话,可以使用request.version来获取值 def get(self, request, *args, **kwargs): print('11111', request.version) if request.version == "v1": ret = { "name": "Frank5555" } elif request.version == "v2": ret = { "name": "Tom" } else: ret = '错误信息' return Response(ret)
把url放在里面:
#版本号放在URL里面 # versioning_class = URLPathVersioning # # def get(self, request, *args, **kwargs): # print('11111', request.version) # from django.urls import reverse # url=reverse(viewname="u",kwargs={"version":'v1'})#django生成的URl需要拼接 # # url=request.versioning_scheme.reverse(viewname='u',request=request)#反向生成URl,这个URL不需要拼接。 # print(url) # if request.version == "v1": # ret = { # "name": "Frank5555" # } # elif request.version == "v2": # ret = { # "name": "Tom" # } # else: # ret = '错误信息' # return Response(ret)
子域名版本:
versioning_class=HostNameVersioning def get(self, request, *args, **kwargs): # print('11111', request.version) # print('222',request.versioning_scheme) if request.version == "v1": ret = { "name": "Frank5555" } elif request.version == "v2": ret = { "name": "Tom" } else: ret = '错误信息' return Response(ret)
上面的设置可以看成时在视图里面设置的。
也可以在全局设置:(只能使用一种)
REST_FRAMEWORK = { 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v1', 'ALLOWED_VERSIONS':['v1','v2'], #'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning" }
2 解释器
文字解释:
请求的数据进行解析:请求体进行解析。表示服务端可以解析的数据格式的种类。 Content-Type: application/url-encoding..... request.body request.POST Content-Type: application/json..... request.body request.POST#里面没有数据 客户端: Content-Type: application/json '{"name":"alex","age":123}' 服务端接收: 读取客户端发送的Content-Type的值 application/json parser_classes = [JSONParser,] 如果客户端的Content-Type的值和 application/json 匹配:JSONParser处理数据 如果客户端的Content-Type的值和 application/x-www-form-urlencoded 匹配:FormParser处理数据 配置: 单视图: class UsersView(APIView): parser_classes = [JSONParser,] 全局配置: REST_FRAMEWORK = { 'VERSION_PARAM':'version', 'DEFAULT_VERSION':'v1', 'ALLOWED_VERSIONS':['v1','v2'], # 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.HostNameVersioning" 'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning", 'DEFAULT_PARSER_CLASSES':[ 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', ] }
from django.shortcuts import render # Create your views here. from django.shortcuts import render from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.authentication import BasicAuthentication from rest_framework.versioning import QueryParameterVersioning,URLPathVersioning,HostNameVersioning from rest_framework.parsers import JSONParser,FormParser class UserView(APIView): def get(self,request,*args,**kwargs): print('生活如此美好') return Response(">>>>>fuck") def post(self,request,*args,**kwargs): #parser_classes = [JSONParser, ]这是局部的 #application/json print('json',request._request.body)#里面放的时Json数据是b"xxxxx" print('json',request._request.POST)#里面没有数据 print('json',request.data) #www-form-url-encode print('body',request._request.body)#字节的形式b'k1=v1&k2=v2' print('post',request._request.POST)# <QueryDict: {'k1': ['v1'], 'k2': ['v2']}> print('encode',request.data) print(request.POST) return Response('.......')
3.序列化
rest framework序列化+From验证
序列化:
对象=》字符串 序列化
字符串=》对象 反序列化
目的:
解决QuerySet序列化问题
用到了路由分发:
"""demo URL Configuration The `urlpatterns` list routes URLs to views. For more information please see: https://docs.djangoproject.com/en/1.11/topics/http/urls/ Examples: Function views 1. Add an import: from my_app import views 2. Add a URL to urlpatterns: url(r'^$', views.home, name='home') Class-based views 1. Add an import: from other_app.views import Home 2. Add a URL to urlpatterns: url(r'^$', Home.as_view(), name='home') Including another URLconf 1. Import the include() function: from django.conf.urls import url, include 2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls')) """ from django.conf.urls import url,include from django.contrib import admin urlpatterns = [ url(r'^admin/', admin.site.urls), # url(r'^app01/(?P<version>[v1|v2]+)/', include('app01.urls')), url(r'^app01/', include('app01.urls')), url(r'^app02/', include('app02.urls')), url(r'^app03/', include('app03.urls')), url(r'^app05/', include('app05.urls')), ]
每个app里面的路由都是大同小异:
from django.conf.urls import url from . import views urlpatterns = [ url(r'^user/', views.UserView.as_view(),name='u'), ]
a.基本操作:
class UsersSerializer(serializers.Serializer): name = serializers.CharField() pwd = serializers.CharField() class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch # 方式一: # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title") # return Response(user_list) # 方式二之多对象 # user_list = models.UserInfo.objects.all() # ser = UsersSerializer(instance=user_list,many=True) # return Response(ser.data) # 方式二之单对象 user = models.UserInfo.objects.all().first() ser = UsersSerializer(instance=user, many=False) return Response(ser.data)
b.跨表操作:
class UsersSerializer(serializers.Serializer): name = serializers.CharField() pwd = serializers.CharField() group_id = serializers.CharField() xxxx = serializers.CharField(source="group.title") x1 = serializers.CharField(source="group.mu.name") class UsersView(APIView): def get(self,request,*args,**kwargs): self.dispatch # 方式一: # user_list = models.UserInfo.objects.all().values('name','pwd','group__id',"group__title") # return Response(user_list) # 方式二之多对象 user_list = models.UserInfo.objects.all() ser = UsersSerializer(instance=user_list,many=True) return Response(ser.data)
c.复杂多对多操作(主要是多对多的显示)
方法一:
from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.authentication import BasicAuthentication
from rest_framework.versioning import QueryParameterVersioning
from rest_framework import serializers
from rest_framework.request import Request
from . import models
class MyCharField(serializers.CharField): def to_representation(self, value): print(value) data_list=[] for row in value: data_list.append(row.name) return data_list class UsersSerializer(serializers.Serializer): name = serializers.CharField() pwd = serializers.CharField() # group_id=serializers.CharField() # xxxx=serializers.CharField(source="group.title") # x1=serializers.CharField(source="group.mu.name") x2=MyCharField(source="roles.all")#多对多建立方法就是更改显示的方式
class UserView(APIView): def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all().first() ser = UsersSerializer(instance=user_list, many=False) return Response(ser.data)
方法二:
class MyCharField(serializers.CharField): def to_representation(self, value): return {'id':value.pk,'name':value.name} class UsersSerializer(serializers.Serializer): name = serializers.CharField() pwd = serializers.CharField() # group_id=serializers.CharField() # xxxx=serializers.CharField(source="group.title") # x1=serializers.CharField(source="group.mu.name") # x2=MyCharField(source="roles.all")#多对多建立方法就是更改显示的方式 x2=serializers.ListField(child=MyCharField(),source="roles.all")
方法三:(推荐使用这个方法因为可以自己修改和加约束条件)
class UsersSerializer(serializers.Serializer): name = serializers.CharField() pwd = serializers.CharField() # group_id=serializers.CharField() # xxxx=serializers.CharField(source="group.title") # x1=serializers.CharField(source="group.mu.name") # x2=MyCharField(source="roles.all")#多对多建立方法就是更改显示的方式 # x2=serializers.ListField(child=MyCharField(),source="roles.all") x2=serializers.SerializerMethodField() def get_x2(self,obj): obj.roles.all() role_list=obj.roles.filter(id__gt=1) data_list=[] for row in role_list: data_list.append({'pk':row.pk,'name':row.name}) return data_list
以上三种都是使用相同的视图:
d.生成Modell时:
class UsersSerializer(serializers.ModelSerializer): class Meta: model=models.UserInfo fields="__all__" class UserView(APIView): def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all().all() ser = UsersSerializer(instance=user_list, many=True) return Response(ser.data)
e.生成Ulr时:
class UsersSerializer(serializers.ModelSerializer): group=serializers.HyperlinkedIdentityField(view_name='detail') class Meta: model=models.UserInfo # fields="__all__" fields=['name','pwd','group'] depth=1 class UserView(APIView): def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all() ser = UsersSerializer(instance=user_list, many=True,context={'request':request}) return Response(ser.data)
url为
from django.conf.urls import url from . import views urlpatterns = [ url(r'^user/', views.UserView.as_view(),name='u'), url(r'^xxxx/(?P<pk>d+)', views.UserView.as_view(),name='detail'), url(r'^xxxx/(?P<pk>d+)', views.UserView.as_view(),name='detail'), url(r'^xxxx/(?P<pk>d+)', views.UserView.as_view(),name='detail'), ]
f生成全局URL时:
class UsersSerializer(serializers.HyperlinkedModelSerializer): class Meta: model=models.UserInfo fields="__all__" # fields=['name','pwd','group'] # depth=1 class UserView(APIView): def get(self, request, *args, **kwargs): user_list = models.UserInfo.objects.all() ser = UsersSerializer(instance=user_list, many=True,context={'request':request}) return Response(ser.data)
它的url:
from django.conf.urls import url from . import views urlpatterns = [ url(r'^user/', views.UserView.as_view(),name='u'), # url(r'^xxxx/(?P<pk>d+)', views.UserView.as_view(),name='detail'), # url(r'^xxxx/(?P<pk>d+)', views.UserView.as_view(),name='detail'), # url(r'^xxxx/(?P<pk>d+)', views.UserView.as_view(),name='detail'), url(r'^xxxx/(?P<pk>d+)', views.UserView.as_view(),name='userinfo-detail'), url(r'^xxxx/(?P<pk>d+)', views.UserView.as_view(),name='group-detail'), url(r'^xxxx/(?P<pk>d+)', views.UserView.as_view(),name='role-detail'), ]
数据验证有两种方式:
a.
class PasswordValidator(object): def __init__(self,base): self.base=base def __call__(self, value): if value !=self.base: message='用户输入的值必须是%s'%self.base raise serializers.ValidationError(message) def set_context(self,serializer_field): pass class UserSeializer(serializers.Serializer): name=serializers.CharField(min_length=6) pwd=serializers.CharField(error_messages={'required':'密码不能为空'},validators=[PasswordValidator('666')]) class UserView(APIView): def get(self,request,*args,**kwargs): user_list=models.UserInfo.objects.all() ser=UserSeializer(instance=user_list,many=True,context={'request':request}) def post(self,request,*args,**kwargs): ser=UserSeializer(data=request.data) if ser.is_valid(): print(ser.validated_data) else: print(ser.errors) return Response('.....')
b.
class PasswordValidator(object): def __init__(self,base): self.base=base def __call__(self, value): if value !=self.base: message='用户输入的值必须是%s'%self.base raise serializers.ValidationError(message) def set_context(self,serializer_field): pass class UserSeializer(serializers.ModelSerializer): class Meta: model=models.UserInfo fields="__all__" extra_kwargs={ 'name':{'min_length':6}, 'pwd':{'validators':[PasswordValidator(666),]} } class UserView(APIView): def get(self,request,*args,**kwargs): user_list=models.UserInfo.objects.all() ser=UserSeializer(instance=user_list,many=True,context={'request':request}) def post(self,request,*args,**kwargs): ser=UserSeializer(data=request.data) if ser.is_valid(): print(ser.validated_data) else: print(ser.errors) return Response('.....')