Django REST framework之版本,解释器,序列化
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('',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('', 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('')])
- 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('.....')
Django REST framework之版本,解释器,序列化的更多相关文章
- Django REST framework 中文教程1:序列化
建立环境 在我们做任何事情之前,我们将使用virtualenv创建一个新的虚拟环境.这将确保我们的包配置与我们正在开展的任何其他项目保持良好的隔离. virtualenv envsource env/ ...
- Django rest framework(6)----序列化
目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...
- Django Rest framework 之 版本
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
- day71:drf:API接口&Restful API规范&Django Rest Framework&drf中的序列化和反序列化功能
目录 1.web应用模式 2.API接口 3.Restful API规范 4.序列化 5.Django Rest Framework 1.drf的简单介绍 2.drf的特点 3.如何安装drf 4.d ...
- Django rest framework 之版本
一.通过 QueryParameterVersioning 获取版本 通过 QueryParameterVersioning 从 get 请求中获取版本信息: 1.新建 app,名为 api,Proj ...
- Django rest framework(6)----序列化(2)
为什么要序列化 django 查询数据库返回的类型是 queryset 类型 而我们和前端通信使用的大多数是json类型,这个时候我们需要把 queryset的数据类型转换成python的数据类型然 ...
- Django rest framework源码分析(4)----版本
版本 新建一个工程Myproject和一个app名为api (1)api/models.py from django.db import models class UserInfo(models.Mo ...
- Django Rest framework 之 序列化
RESTful 规范 django rest framework 之 认证(一) django rest framework 之 权限(二) django rest framework 之 节流(三) ...
- Django rest framework(4)----版本
目录 Django组件库之(一) APIView源码 Django restframework (1) ----认证 Django rest framework(2)----权限 Django res ...
随机推荐
- php防止刷流量攻击
<?php //查询禁止IP $ip =$_SERVER['REMOTE_ADDR']; $fileht=".htaccess2"; if(!file_exists($fil ...
- wepack---预打包dll
一.前言 今天被问到,怎么实现webpack快速打包?话说距离上次手动配置webpack已经过去很长时间了,现在webpack都出到4.0版本了,号称零配置,还没来得及好好感受一下. ‘不就是公共模块 ...
- 一个比较好用的省内存的ORM
http://www.52chloe.com 记录一下,完了,就这样
- csharp: Setting the value of properties reflection
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- foreach 引发的值类型与引用类型思考
用都知道的一句话概括:“引用类型在堆上,栈上只保存引用:值类型即可存放于栈上也可存放于堆上,值类型变量直接存储值本身”. class Program { static void Main(string ...
- webpack4 系列教程(一): 打包JS
webpack 本身就是为了打包js所设计,作为第一节,介绍怎么打包js. 1. 检验webpack规范支持 webpack支持es6, CommonJS, AMD. 创建vendor文件夹,其中mi ...
- canvas-star5.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Python 练习: 打印0到99小于50或大于70的数字
for i in range(100): if i < 50 or i > 70: print(i) 注意: range(100) 表示 0 到 99 个数字
- a标签禁止跳转或者不跳转的几种实现方式
1.onclick事件中返回false <a href="http://www.baidu.com" onclick="return false" &g ...
- 【工具相关】Web-将网站放在XAMPP上面
一,将XAMPP服务器打开--->Welcome--->Open Application Folder. 二,会出现如下所示界面.找到htdocs. 三,打开htdocs.如下图所示. 四 ...