博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django Rest Framework
阅读量:7043 次
发布时间:2019-06-28

本文共 52811 字,大约阅读时间需要 176 分钟。

什么是RESTful?

  • REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
  • REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态
  • REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
  • 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
  • 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture)

 

RESTful API设计规范

1.API使用HTTPS与用户进行通信

2.域名

  • https://api.example.com
  • https://example.com/api/

3.版本

  • https://example.com/api/v1/
  • https://api.example.com/v1
  • 设置请求头(跨域时会引发多次请求)

4.路径

  • https://example.com/api/v1/orders/
  • https://example.com/api/v1/animals/

5.method

  • GET :从服务器上获取资源(一项或多项)
  • POST :在服务器上新建一个资源
  • PUT :在服务器更新资源(客户端提供改变后的完整资源)
  • DELETE :从服务器删除资源
  • PATCH :在服务器更新资源(客户端提供改变的属性,局部)

6.过滤(URL进行传参)

  • https://example.com/api/v1/orders?limit=10

  • https://example.com/api/v1/orders?offset=10

  • https://example.com/api/v1/orders?page=10

7.状态码

200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)204 NO CONTENT - [DELETE]:用户删除数据成功。400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html

8.错误处理 状态时4xx时,应该返回错误信息,error当中key

{    error: "Invalid API key"}

9.返回结果,针对不同操作,服务器返回符合规范的结果

GET /order:返回资源对象的列表(数组)GET /order/1:返回单个资源对象POST /order/:返回新生成的资源对象PUT /order/1:返回完整的资源对象PATCH /order/1:返回完整的资源对象DELETE /order/1:返回一个空文档

10.Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。

{
"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json"}}

 

 

Django Rest Framework框架实现

基本流程

urls.py

from django.conf.urls import url, includefrom app01 import viewsurlpatterns = [    url(r'index', views.IndexView.as_view()),]

views.py

from rest_framework.views import APIViewfrom rest_framework.response import Responseclass IndexView(APIView):    def dispatch(self, request, *args, **kwargs):        print('before')        ret = super(IndexView, self).dispatch(request, *args, **kwargs)        print('after')        return ret    def get(self, request):        return Response('GET')    def post(self, request):        print('执行post')        return Response('POST')    def put(self, request):        return Response('PUT')    def delete(self, request):        return Response('delete')

 

认证和授权

a.用户url传入token的认证

from django.conf.urls import url, includefrom web.viewsimport TestViewurlpatterns = [    url(r'^test/', TestView.as_view()),]urls.py
View Code
from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.authentication import BaseAuthenticationfrom rest_framework.request import Requestfrom rest_framework import exceptionstoken_list = [    'sfsfss123kuf3j123',    'asijnfowerkkf9812',]class TestAuthentication(BaseAuthentication):    def authenticate(self, request):        """        用户认证,如果验证成功后返回元组: (用户,用户Token)        :param request:         :return:             None,表示跳过该验证;                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置                self._authenticator = None                if api_settings.UNAUTHENTICATED_USER:                    self.user = api_settings.UNAUTHENTICATED_USER()                else:                    self.user = None                        if api_settings.UNAUTHENTICATED_TOKEN:                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()                else:                    self.auth = None            (user,token)表示验证通过并设置用户名和Token;            AuthenticationFailed异常        """        val = request.query_params.get('token')        if val not in token_list:            raise exceptions.AuthenticationFailed("用户认证失败")        return ('登录用户', '用户token')    def authenticate_header(self, request):        """        Return a string to be used as the value of the `WWW-Authenticate`        header in a `401 Unauthenticated` response, or `None` if the        authentication scheme should return `403 Permission Denied` responses.        """        # 验证失败时,返回的响应头WWW-Authenticate对应的值        passclass TestView(APIView):    authentication_classes = [TestAuthentication, ]    permission_classes = []    def get(self, request, *args, **kwargs):        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
View Code

b.请求头认证

from django.conf.urls import url, includefrom web.viewsimport TestViewurlpatterns = [    url(r'^test/', TestView.as_view()),]urls.py
View Code
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.authentication import BaseAuthenticationfrom rest_framework.request import Requestfrom rest_framework import exceptionstoken_list = [    'sfsfss123kuf3j123',    'asijnfowerkkf9812',]class TestAuthentication(BaseAuthentication):    def authenticate(self, request):        """        用户认证,如果验证成功后返回元组: (用户,用户Token)        :param request:         :return:             None,表示跳过该验证;                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置                self._authenticator = None                if api_settings.UNAUTHENTICATED_USER:                    self.user = api_settings.UNAUTHENTICATED_USER()                else:                    self.user = None                        if api_settings.UNAUTHENTICATED_TOKEN:                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()                else:                    self.auth = None            (user,token)表示验证通过并设置用户名和Token;            AuthenticationFailed异常        """        import base64        auth = request.META.get('HTTP_AUTHORIZATION', b'')        if auth:            auth = auth.encode('utf-8')        auth = auth.split()        if not auth or auth[0].lower() != b'basic':            raise exceptions.AuthenticationFailed('验证失败')        if len(auth) != 2:            raise exceptions.AuthenticationFailed('验证失败')        username, part, password = base64.b64decode(auth[1]).decode('utf-8').partition(':')        if username == 'alex' and password == '123':            return ('登录用户', '用户token')        else:            raise exceptions.AuthenticationFailed('用户名或密码错误')    def authenticate_header(self, request):        """        Return a string to be used as the value of the `WWW-Authenticate`        header in a `401 Unauthenticated` response, or `None` if the        authentication scheme should return `403 Permission Denied` responses.        """        return 'Basic realm=api'class TestView(APIView):    authentication_classes = [TestAuthentication, ]    permission_classes = []    def get(self, request, *args, **kwargs):        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py

View Code

c.多个认证规则

from django.conf.urls import url, includefrom web.views.s2_auth import TestViewurlpatterns = [    url(r'^test/', TestView.as_view()),]urls.py
View Code
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.authentication import BaseAuthenticationfrom rest_framework.request import Requestfrom rest_framework import exceptionstoken_list = [    'sfsfss123kuf3j123',    'asijnfowerkkf9812',]class Test1Authentication(BaseAuthentication):    def authenticate(self, request):        """        用户认证,如果验证成功后返回元组: (用户,用户Token)        :param request:         :return:             None,表示跳过该验证;                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置                self._authenticator = None                if api_settings.UNAUTHENTICATED_USER:                    self.user = api_settings.UNAUTHENTICATED_USER() # 默认值为:匿名用户                else:                    self.user = None                if api_settings.UNAUTHENTICATED_TOKEN:                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默认值为:None                else:                    self.auth = None            (user,token)表示验证通过并设置用户名和Token;            AuthenticationFailed异常        """        import base64        auth = request.META.get('HTTP_AUTHORIZATION', b'')        if auth:            auth = auth.encode('utf-8')        else:            return None        print(auth,'xxxx')        auth = auth.split()        if not auth or auth[0].lower() != b'basic':            raise exceptions.AuthenticationFailed('验证失败')        if len(auth) != 2:            raise exceptions.AuthenticationFailed('验证失败')        username, part, password = base64.b64decode(auth[1]).decode('utf-8').partition(':')        if username == 'alex' and password == '123':            return ('登录用户', '用户token')        else:            raise exceptions.AuthenticationFailed('用户名或密码错误')    def authenticate_header(self, request):        """        Return a string to be used as the value of the `WWW-Authenticate`        header in a `401 Unauthenticated` response, or `None` if the        authentication scheme should return `403 Permission Denied` responses.        """        # return 'Basic realm=api'        passclass Test2Authentication(BaseAuthentication):    def authenticate(self, request):        """        用户认证,如果验证成功后返回元组: (用户,用户Token)        :param request:         :return:             None,表示跳过该验证;                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置                self._authenticator = None                if api_settings.UNAUTHENTICATED_USER:                    self.user = api_settings.UNAUTHENTICATED_USER() # 默认值为:匿名用户                else:                    self.user = None                        if api_settings.UNAUTHENTICATED_TOKEN:                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默认值为:None                else:                    self.auth = None            (user,token)表示验证通过并设置用户名和Token;            AuthenticationFailed异常        """        val = request.query_params.get('token')        if val not in token_list:            raise exceptions.AuthenticationFailed("用户认证失败")        return ('登录用户', '用户token')    def authenticate_header(self, request):        """        Return a string to be used as the value of the `WWW-Authenticate`        header in a `401 Unauthenticated` response, or `None` if the        authentication scheme should return `403 Permission Denied` responses.        """        passclass TestView(APIView):    authentication_classes = [Test1Authentication, Test2Authentication]    permission_classes = []    def get(self, request, *args, **kwargs):        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
View Code

d.认证和权限

from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^test/', TestView.as_view()),]urls.py
View Code
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.authentication import BaseAuthenticationfrom rest_framework.permissions import BasePermissionfrom rest_framework.request import Requestfrom rest_framework import exceptionstoken_list = [    'sfsfss123kuf3j123',    'asijnfowerkkf9812',]class TestAuthentication(BaseAuthentication):    def authenticate(self, request):        """        用户认证,如果验证成功后返回元组: (用户,用户Token)        :param request:         :return:             None,表示跳过该验证;                如果跳过了所有认证,默认用户和Token和使用配置文件进行设置                self._authenticator = None                if api_settings.UNAUTHENTICATED_USER:                    self.user = api_settings.UNAUTHENTICATED_USER() # 默认值为:匿名用户                else:                    self.user = None                        if api_settings.UNAUTHENTICATED_TOKEN:                    self.auth = api_settings.UNAUTHENTICATED_TOKEN()# 默认值为:None                else:                    self.auth = None            (user,token)表示验证通过并设置用户名和Token;            AuthenticationFailed异常        """        val = request.query_params.get('token')        if val not in token_list:            raise exceptions.AuthenticationFailed("用户认证失败")        return ('登录用户', '用户token')    def authenticate_header(self, request):        """        Return a string to be used as the value of the `WWW-Authenticate`        header in a `401 Unauthenticated` response, or `None` if the        authentication scheme should return `403 Permission Denied` responses.        """        passclass TestPermission(BasePermission):    message = "权限验证失败"    def has_permission(self, request, view):        """        判断是否有权限访问当前请求        Return `True` if permission is granted, `False` otherwise.        :param request:         :param view:         :return: True有权限;False无权限        """        if request.user == "管理员":            return True    # GenericAPIView中get_object时调用    def has_object_permission(self, request, view, obj):        """        视图继承GenericAPIView,并在其中使用get_object时获取对象时,触发单独对象权限验证        Return `True` if permission is granted, `False` otherwise.        :param request:         :param view:         :param obj:         :return: True有权限;False无权限        """        if request.user == "管理员":            return Trueclass TestView(APIView):    # 认证的动作是由request.user触发    authentication_classes = [TestAuthentication, ]    # 权限    # 循环执行所有的权限    permission_classes = [TestPermission, ]    def get(self, request, *args, **kwargs):        # self.dispatch        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
View Code

e.全局使用

上述操作中均是对单独视图进行特殊配置,如果想要对全局进行配置,则需要再配置文件中写入即可。

REST_FRAMEWORK = {    'UNAUTHENTICATED_USER': None,    'UNAUTHENTICATED_TOKEN': None,    "DEFAULT_AUTHENTICATION_CLASSES": [        "web.utils.TestAuthentication",    ],    "DEFAULT_PERMISSION_CLASSES": [        "web.utils.TestPermission",    ],}settings.py
settings.py
from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^test/', TestView.as_view()),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responseclass TestView(APIView):    def get(self, request, *args, **kwargs):        # self.dispatch        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

 

用户访问次数/频率限制

a.基于用户IP限制访问频率

from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^test/', TestView.as_view()),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-import timefrom rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import exceptionsfrom rest_framework.throttling import BaseThrottlefrom rest_framework.settings import api_settings# 保存访问记录RECORD = {    '用户IP': [12312139, 12312135, 12312133, ]}class TestThrottle(BaseThrottle):    ctime = time.time    def get_ident(self, request):        """        根据用户IP和代理IP,当做请求者的唯一IP        Identify the machine making the request by parsing HTTP_X_FORWARDED_FOR        if present and number of proxies is > 0. If not use all of        HTTP_X_FORWARDED_FOR if it is available, if not use REMOTE_ADDR.        """        xff = request.META.get('HTTP_X_FORWARDED_FOR')        remote_addr = request.META.get('REMOTE_ADDR')        num_proxies = api_settings.NUM_PROXIES        if num_proxies is not None:            if num_proxies == 0 or xff is None:                return remote_addr            addrs = xff.split(',')            client_addr = addrs[-min(num_proxies, len(addrs))]            return client_addr.strip()        return ''.join(xff.split()) if xff else remote_addr    def allow_request(self, request, view):        """        是否仍然在允许范围内        Return `True` if the request should be allowed, `False` otherwise.        :param request:         :param view:         :return: True,表示可以通过;False表示已超过限制,不允许访问        """        # 获取用户唯一标识(如:IP)        # 允许一分钟访问10次        num_request = 10        time_request = 60        now = self.ctime()        ident = self.get_ident(request)        self.ident = ident        if ident not in RECORD:            RECORD[ident] = [now, ]            return True        history = RECORD[ident]        while history and history[-1] <= now - time_request:            history.pop()        if len(history) < num_request:            history.insert(0, now)            return True    def wait(self):        """        多少秒后可以允许继续访问        Optionally, return a recommended number of seconds to wait before        the next request.        """        last_time = RECORD[self.ident][0]        now = self.ctime()        return int(60 + last_time - now)class TestView(APIView):    throttle_classes = [TestThrottle, ]    def get(self, request, *args, **kwargs):        # self.dispatch        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')    def throttled(self, request, wait):        """        访问次数被限制时,定制错误信息        """        class Throttled(exceptions.Throttled):            default_detail = '请求被限制.'            extra_detail_singular = '请 {wait} 秒之后再重试.'            extra_detail_plural = '请 {wait} 秒之后再重试.'        raise Throttled(wait)views.py
views.py

b. 基于用户IP显示访问频率(利于Django缓存)

REST_FRAMEWORK = {    'DEFAULT_THROTTLE_RATES': {        'test_scope': '10/m',    },}
settings.py
from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^test/', TestView.as_view()),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import exceptionsfrom rest_framework.throttling import SimpleRateThrottleclass TestThrottle(SimpleRateThrottle):    # 配置文件定义的显示频率的Key    scope = "test_scope"    def get_cache_key(self, request, view):        """        Should return a unique cache-key which can be used for throttling.        Must be overridden.        May return `None` if the request should not be throttled.        """        if not request.user:            ident = self.get_ident(request)        else:            ident = request.user        return self.cache_format % {            'scope': self.scope,            'ident': ident        }class TestView(APIView):    throttle_classes = [TestThrottle, ]    def get(self, request, *args, **kwargs):        # self.dispatch        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')    def throttled(self, request, wait):        """        访问次数被限制时,定制错误信息        """        class Throttled(exceptions.Throttled):            default_detail = '请求被限制.'            extra_detail_singular = '请 {wait} 秒之后再重试.'            extra_detail_plural = '请 {wait} 秒之后再重试.'        raise Throttled(wait)views.py
views.py

c. view中限制请求频率

REST_FRAMEWORK = {    'DEFAULT_THROTTLE_RATES': {        'xxxxxx': '10/m',    },}
settings.py
from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^test/', TestView.as_view()),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import exceptionsfrom rest_framework.throttling import ScopedRateThrottle# 继承 ScopedRateThrottleclass TestThrottle(ScopedRateThrottle):    def get_cache_key(self, request, view):        """        Should return a unique cache-key which can be used for throttling.        Must be overridden.        May return `None` if the request should not be throttled.        """        if not request.user:            ident = self.get_ident(request)        else:            ident = request.user        return self.cache_format % {            'scope': self.scope,            'ident': ident        }class TestView(APIView):    throttle_classes = [TestThrottle, ]    # 在settings中获取 xxxxxx 对应的频率限制值    throttle_scope = "xxxxxx"    def get(self, request, *args, **kwargs):        # self.dispatch        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')    def throttled(self, request, wait):        """        访问次数被限制时,定制错误信息        """        class Throttled(exceptions.Throttled):            default_detail = '请求被限制.'            extra_detail_singular = '请 {wait} 秒之后再重试.'            extra_detail_plural = '请 {wait} 秒之后再重试.'        raise Throttled(wait)views.py
views.py

d. 匿名时用IP限制+登录时用Token限制

REST_FRAMEWORK = {    'UNAUTHENTICATED_USER': None,    'UNAUTHENTICATED_TOKEN': None,    'DEFAULT_THROTTLE_RATES': {        'luffy_anon': '10/m',        'luffy_user': '20/m',    },}settings.py
settings.py
from django.conf.urls import url, includefrom web.views.s3_throttling import TestViewurlpatterns = [    url(r'^test/', TestView.as_view()),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.throttling import SimpleRateThrottleclass LuffyAnonRateThrottle(SimpleRateThrottle):    """    匿名用户,根据IP进行限制    """    scope = "luffy_anon"    def get_cache_key(self, request, view):        # 用户已登录,则跳过 匿名频率限制        if request.user:            return None        return self.cache_format % {            'scope': self.scope,            'ident': self.get_ident(request)        }class LuffyUserRateThrottle(SimpleRateThrottle):    """    登录用户,根据用户token限制    """    scope = "luffy_user"    def get_ident(self, request):        """        认证成功时:request.user是用户对象;request.auth是token对象        :param request:         :return:         """        # return request.auth.token        return "user_token"    def get_cache_key(self, request, view):        """        获取缓存key        :param request:         :param view:         :return:         """        # 未登录用户,则跳过 Token限制        if not request.user:            return None        return self.cache_format % {            'scope': self.scope,            'ident': self.get_ident(request)        }class TestView(APIView):    throttle_classes = [LuffyUserRateThrottle, LuffyAnonRateThrottle, ]    def get(self, request, *args, **kwargs):        # self.dispatch        print(request.user)        print(request.auth)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

e.全局使用

REST_FRAMEWORK = {    'DEFAULT_THROTTLE_CLASSES': [        'api.utils.throttles.throttles.LuffyAnonRateThrottle',        'api.utils.throttles.throttles.LuffyUserRateThrottle',    ],    'DEFAULT_THROTTLE_RATES': {        'anon': '10/day',        'user': '10/day',        'luffy_anon': '10/m',        'luffy_user': '20/m',    },}settings
settings

 

版本

a.基于url的get传参方式

如:/users?version=v1

REST_FRAMEWORK = {    'DEFAULT_VERSION': 'v1',            # 默认版本    'ALLOWED_VERSIONS': ['v1', 'v2'],   # 允许的版本    'VERSION_PARAM': 'version'          # URL中获取值的key}
settings.py
from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^test/', TestView.as_view(),name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.versioning import QueryParameterVersioningclass TestView(APIView):    versioning_class = QueryParameterVersioning    def get(self, request, *args, **kwargs):        # 获取版本        print(request.version)        # 获取版本管理的类        print(request.versioning_scheme)        # 反向生成URL        reverse_url = request.versioning_scheme.reverse('test', request=request)        print(reverse_url)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

b. 基于url的正则方式

如:/v1/users/  

REST_FRAMEWORK = {    'DEFAULT_VERSION': 'v1',            # 默认版本    'ALLOWED_VERSIONS': ['v1', 'v2'],   # 允许的版本    'VERSION_PARAM': 'version'          # URL中获取值的key}
settings.py
from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^(?P
[v1|v2]+)/test/', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.versioning import URLPathVersioningclass TestView(APIView):    versioning_class = URLPathVersioning    def get(self, request, *args, **kwargs):        # 获取版本        print(request.version)        # 获取版本管理的类        print(request.versioning_scheme)        # 反向生成URL        reverse_url = request.versioning_scheme.reverse('test', request=request)        print(reverse_url)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

c. 基于 accept 请求头方式

如:Accept: application/json; version=1.0

REST_FRAMEWORK = {    'DEFAULT_VERSION': 'v1',            # 默认版本    'ALLOWED_VERSIONS': ['v1', 'v2'],   # 允许的版本    'VERSION_PARAM': 'version'          # URL中获取值的key}
settings.py
from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^test/', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.versioning import AcceptHeaderVersioningclass TestView(APIView):    versioning_class = AcceptHeaderVersioning    def get(self, request, *args, **kwargs):        # 获取版本 HTTP_ACCEPT头        print(request.version)        # 获取版本管理的类        print(request.versioning_scheme)        # 反向生成URL        reverse_url = request.versioning_scheme.reverse('test', request=request)        print(reverse_url)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

d. 基于主机名方法

如:v1.example.com

ALLOWED_HOSTS = ['*']REST_FRAMEWORK = {    'DEFAULT_VERSION': 'v1',  # 默认版本    'ALLOWED_VERSIONS': ['v1', 'v2'],  # 允许的版本    'VERSION_PARAM': 'version'  # URL中获取值的key}settings.py
settings.py
from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^test/', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.versioning import HostNameVersioningclass TestView(APIView):    versioning_class = HostNameVersioning    def get(self, request, *args, **kwargs):        # 获取版本        print(request.version)        # 获取版本管理的类        print(request.versioning_scheme)        # 反向生成URL        reverse_url = request.versioning_scheme.reverse('test', request=request)        print(reverse_url)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

e. 基于django路由系统的namespace

如:example.com/v1/users/

REST_FRAMEWORK = {    'DEFAULT_VERSION': 'v1',  # 默认版本    'ALLOWED_VERSIONS': ['v1', 'v2'],  # 允许的版本    'VERSION_PARAM': 'version'  # URL中获取值的key}
settings.py
from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'^v1/', ([                      url(r'test/', TestView.as_view(), name='test'),                  ], None, 'v1')),    url(r'^v2/', ([                      url(r'test/', TestView.as_view(), name='test'),                  ], None, 'v2')),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.versioning import NamespaceVersioningclass TestView(APIView):    versioning_class = NamespaceVersioning    def get(self, request, *args, **kwargs):        # 获取版本        print(request.version)        # 获取版本管理的类        print(request.versioning_scheme)        # 反向生成URL        reverse_url = request.versioning_scheme.reverse('test', request=request)        print(reverse_url)        return Response('GET请求,响应内容')    def post(self, request, *args, **kwargs):        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

f. 全局使用

REST_FRAMEWORK = {    'DEFAULT_VERSIONING_CLASS':"rest_framework.versioning.URLPathVersioning",    'DEFAULT_VERSION': 'v1',    'ALLOWED_VERSIONS': ['v1', 'v2'],    'VERSION_PARAM': 'version' }settings.py
settings.py

 

解析器(parser) 

根据请求头 content-type 选择对应的解析器就请求体内容进行处理。

a. 仅处理请求头content-type为application/json的请求体

from django.conf.urls import url, includefrom web.views.s5_parser import TestViewurlpatterns = [    url(r'test/', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.request import Requestfrom rest_framework.parsers import JSONParserclass TestView(APIView):    parser_classes = [JSONParser, ]    def post(self, request, *args, **kwargs):        print(request.content_type)        # 获取请求的值,并使用对应的JSONParser进行处理        print(request.data)        # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值        print(request.POST)        print(request.FILES)        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

b. 仅处理请求头content-type为application/x-www-form-urlencoded 的请求体

from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'test/', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.request import Requestfrom rest_framework.parsers import FormParserclass TestView(APIView):    parser_classes = [FormParser, ]    def post(self, request, *args, **kwargs):        print(request.content_type)        # 获取请求的值,并使用对应的JSONParser进行处理        print(request.data)        # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值        print(request.POST)        print(request.FILES)        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

c. 仅处理请求头content-type为multipart/form-data的请求体

from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'test/', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.request import Requestfrom rest_framework.parsers import MultiPartParserclass TestView(APIView):    parser_classes = [MultiPartParser, ]    def post(self, request, *args, **kwargs):        print(request.content_type)        # 获取请求的值,并使用对应的JSONParser进行处理        print(request.data)        # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值        print(request.POST)        print(request.FILES)        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py
    
Title
upload.html
upload.html

d. 仅上传文件

from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'test/(?P
[^/]+)', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.request import Requestfrom rest_framework.parsers import FileUploadParserclass TestView(APIView):    parser_classes = [FileUploadParser, ]    def post(self, request, filename, *args, **kwargs):        print(filename)        print(request.content_type)        # 获取请求的值,并使用对应的JSONParser进行处理        print(request.data)        # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值        print(request.POST)        print(request.FILES)        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py
    
Title
upload.html
upload.html

e. 同时多个Parser

当同时使用多个parser时,rest framework会根据请求头content-type自动进行比对,并使用对应parser

from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'test/', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework.request import Requestfrom rest_framework.parsers import JSONParser, FormParser, MultiPartParserclass TestView(APIView):    parser_classes = [JSONParser, FormParser, MultiPartParser, ]    def post(self, request, *args, **kwargs):        print(request.content_type)        # 获取请求的值,并使用对应的JSONParser进行处理        print(request.data)        # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值        print(request.POST)        print(request.FILES)        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

f. 全局使用

REST_FRAMEWORK = {    'DEFAULT_PARSER_CLASSES':[        'rest_framework.parsers.JSONParser'        'rest_framework.parsers.FormParser'        'rest_framework.parsers.MultiPartParser'    ]}settings.py
settings.py
from django.conf.urls import url, includefrom web.views import TestViewurlpatterns = [    url(r'test/', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responseclass TestView(APIView):    def post(self, request, *args, **kwargs):        print(request.content_type)        # 获取请求的值,并使用对应的JSONParser进行处理        print(request.data)        # application/x-www-form-urlencoded 或 multipart/form-data时,request.POST中才有值        print(request.POST)        print(request.FILES)        return Response('POST请求,响应内容')    def put(self, request, *args, **kwargs):        return Response('PUT请求,响应内容')views.py
views.py

注意:个别特殊的值可以通过Django的request对象 request._request 来进行获取

 

序列化

序列化用于对用户请求数据进行验证和数据进行序列化。

a. 自定义字段

from django.conf.urls import url, includefrom web.views.s6_serializers import TestViewurlpatterns = [    url(r'test/', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import serializersfrom .. import modelsclass PasswordValidator(object):    def __init__(self, base):        self.base = base    def __call__(self, value):        if value != self.base:            message = 'This field must be %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是当前字段对象        passclass UserSerializer(serializers.Serializer):    ut_title = serializers.CharField(source='ut.title')    user = serializers.CharField(min_length=6)    pwd = serializers.CharField(error_messages={
'required': '密码不能为空'}, validators=[PasswordValidator('666')])class TestView(APIView): def get(self, request, *args, **kwargs): # 序列化,将数据库查询字段序列化为字典 data_list = models.UserInfo.objects.all() ser = UserSerializer(instance=data_list, many=True) # 或 # obj = models.UserInfo.objects.all().first() # ser = UserSerializer(instance=obj, many=False) return Response(ser.data) def post(self, request, *args, **kwargs): # 验证,对请求发来的数据进行验证 ser = UserSerializer(data=request.data) if ser.is_valid(): print(ser.validated_data) else: print(ser.errors) return Response('POST请求,响应内容')views.py
views.py

b. 基于Model自动生成字段

from django.conf.urls import url, includefrom web.views.s6_serializers import TestViewurlpatterns = [    url(r'test/', TestView.as_view(), name='test'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import serializersfrom .. import modelsclass PasswordValidator(object):    def __init__(self, base):        self.base = str(base)    def __call__(self, value):        if value != self.base:            message = 'This field must be %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是当前字段对象        passclass ModelUserSerializer(serializers.ModelSerializer):    user = serializers.CharField(max_length=32)    class Meta:        model = models.UserInfo        fields = "__all__"        # fields = ['user', 'pwd', 'ut']        depth = 2        extra_kwargs = {
'user': {
'min_length': 6}, 'pwd': {
'validators': [PasswordValidator(666), ]}} # read_only_fields = ['user']class TestView(APIView): def get(self, request, *args, **kwargs): # 序列化,将数据库查询字段序列化为字典 data_list = models.UserInfo.objects.all() ser = ModelUserSerializer(instance=data_list, many=True) # 或 # obj = models.UserInfo.objects.all().first() # ser = UserSerializer(instance=obj, many=False) return Response(ser.data) def post(self, request, *args, **kwargs): # 验证,对请求发来的数据进行验证 print(request.data) ser = ModelUserSerializer(data=request.data) if ser.is_valid(): print(ser.validated_data) else: print(ser.errors) return Response('POST请求,响应内容')views.py
views.py

c. 生成URL

from django.conf.urls import url, includefrom web.views.s6_serializers import TestViewurlpatterns = [    url(r'test/', TestView.as_view(), name='test'),    url(r'detail/(?P
\d+)/', TestView.as_view(), name='detail'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import serializersfrom .. import modelsclass PasswordValidator(object):    def __init__(self, base):        self.base = str(base)    def __call__(self, value):        if value != self.base:            message = 'This field must be %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是当前字段对象        passclass ModelUserSerializer(serializers.ModelSerializer):    ut = serializers.HyperlinkedIdentityField(view_name='detail')    class Meta:        model = models.UserInfo        fields = "__all__"        extra_kwargs = {            'user': {
'min_length': 6}, 'pwd': {
'validators': [PasswordValidator(666),]}, }class TestView(APIView): def get(self, request, *args, **kwargs): # 序列化,将数据库查询字段序列化为字典 data_list = models.UserInfo.objects.all() ser = ModelUserSerializer(instance=data_list, many=True, context={
'request': request}) # 或 # obj = models.UserInfo.objects.all().first() # ser = UserSerializer(instance=obj, many=False) return Response(ser.data) def post(self, request, *args, **kwargs): # 验证,对请求发来的数据进行验证 print(request.data) ser = ModelUserSerializer(data=request.data) if ser.is_valid(): print(ser.validated_data) else: print(ser.errors) return Response('POST请求,响应内容')views.py
views.py

d. 自动生成URL

from django.conf.urls import url, includefrom web.views.s6_serializers import TestViewurlpatterns = [    url(r'test/', TestView.as_view(), name='test'),    url(r'detail/(?P
\d+)/', TestView.as_view(), name='xxxx'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom rest_framework import serializersfrom .. import modelsclass PasswordValidator(object):    def __init__(self, base):        self.base = str(base)    def __call__(self, value):        if value != self.base:            message = 'This field must be %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是当前字段对象        passclass ModelUserSerializer(serializers.HyperlinkedModelSerializer):    ll = serializers.HyperlinkedIdentityField(view_name='xxxx')    tt = serializers.CharField(required=False)    class Meta:        model = models.UserInfo        fields = "__all__"        list_serializer_class = serializers.ListSerializer        extra_kwargs = {            'user': {
'min_length': 6}, 'pwd': {
'validators': [PasswordValidator(666), ]}, 'url': {
'view_name': 'xxxx'}, 'ut': {
'view_name': 'xxxx'}, }class TestView(APIView): def get(self, request, *args, **kwargs): # # 序列化,将数据库查询字段序列化为字典 data_list = models.UserInfo.objects.all() ser = ModelUserSerializer(instance=data_list, many=True, context={
'request': request}) # # 如果Many=True # # 或 # # obj = models.UserInfo.objects.all().first() # # ser = UserSerializer(instance=obj, many=False) return Response(ser.data) def post(self, request, *args, **kwargs): # 验证,对请求发来的数据进行验证 print(request.data) ser = ModelUserSerializer(data=request.data) if ser.is_valid(): print(ser.validated_data) else: print(ser.errors) return Response('POST请求,响应内容')views.py
views.py

 

7. 分页

a. 根据页码进行分页

from django.conf.urls import url, includefrom rest_framework import routersfrom web.views import s9_paginationurlpatterns = [    url(r'^test/', s9_pagination.UserViewSet.as_view()),]urs.py
urs.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework import serializersfrom .. import modelsfrom rest_framework.pagination import PageNumberPaginationclass StandardResultsSetPagination(PageNumberPagination):    # 默认每页显示的数据条数    page_size = 1    # 获取URL参数中设置的每页显示数据条数    page_size_query_param = 'page_size'    # 获取URL参数中传入的页码key    page_query_param = 'page'    # 最大支持的每页显示的数据条数    max_page_size = 1class UserSerializer(serializers.ModelSerializer):    class Meta:        model = models.UserInfo        fields = "__all__"class UserViewSet(APIView):    def get(self, request, *args, **kwargs):        user_list = models.UserInfo.objects.all().order_by('-id')        # 实例化分页对象,获取数据库中的分页数据        paginator = StandardResultsSetPagination()        page_user_list = paginator.paginate_queryset(user_list, self.request, view=self)        # 序列化对象        serializer = UserSerializer(page_user_list, many=True)        # 生成分页和数据        response = paginator.get_paginated_response(serializer.data)        return responseviews.py
views.py

b. 位置和个数进行分页

from django.conf.urls import url, includefrom web.views import s9_paginationurlpatterns = [    url(r'^test/', s9_pagination.UserViewSet.as_view()),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework import serializersfrom .. import modelsfrom rest_framework.pagination import PageNumberPagination,LimitOffsetPaginationclass StandardResultsSetPagination(LimitOffsetPagination):    # 默认每页显示的数据条数    default_limit = 10    # URL中传入的显示数据条数的参数    limit_query_param = 'limit'    # URL中传入的数据位置的参数    offset_query_param = 'offset'    # 最大每页显得条数    max_limit = Noneclass UserSerializer(serializers.ModelSerializer):    class Meta:        model = models.UserInfo        fields = "__all__"class UserViewSet(APIView):    def get(self, request, *args, **kwargs):        user_list = models.UserInfo.objects.all().order_by('-id')        # 实例化分页对象,获取数据库中的分页数据        paginator = StandardResultsSetPagination()        page_user_list = paginator.paginate_queryset(user_list, self.request, view=self)        # 序列化对象        serializer = UserSerializer(page_user_list, many=True)        # 生成分页和数据        response = paginator.get_paginated_response(serializer.data)        return responseviews.py
views.py

c. 游标分页

from django.conf.urls import url, includefrom web.views import s9_paginationurlpatterns = [    url(r'^test/', s9_pagination.UserViewSet.as_view()),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.views import APIViewfrom rest_framework import serializersfrom .. import modelsfrom rest_framework.pagination import PageNumberPagination, LimitOffsetPagination, CursorPaginationclass StandardResultsSetPagination(CursorPagination):    # URL传入的游标参数    cursor_query_param = 'cursor'    # 默认每页显示的数据条数    page_size = 2    # URL传入的每页显示条数的参数    page_size_query_param = 'page_size'    # 每页显示数据最大条数    max_page_size = 1000    # 根据ID从大到小排列    ordering = "id"class UserSerializer(serializers.ModelSerializer):    class Meta:        model = models.UserInfo        fields = "__all__"class UserViewSet(APIView):    def get(self, request, *args, **kwargs):        user_list = models.UserInfo.objects.all().order_by('-id')        # 实例化分页对象,获取数据库中的分页数据        paginator = StandardResultsSetPagination()        page_user_list = paginator.paginate_queryset(user_list, self.request, view=self)        # 序列化对象        serializer = UserSerializer(page_user_list, many=True)        # 生成分页和数据        response = paginator.get_paginated_response(serializer.data)        return responseviews.py
views.py

 

8. 路由系统

a. 自定义路由

from django.conf.urls import url, includefrom web.views import s11_renderurlpatterns = [    url(r'^test/$', s11_render.TestView.as_view()),    url(r'^test\.(?P
[a-z0-9]+)$', s11_render.TestView.as_view()), url(r'^test/(?P
[^/.]+)/$', s11_render.TestView.as_view()), url(r'^test/(?P
[^/.]+)\.(?P
[a-z0-9]+)$', s11_render.TestView.as_view())]urls.py
urls.py
from rest_framework.views import APIViewfrom rest_framework.response import Responsefrom .. import modelsclass TestView(APIView):    def get(self, request, *args, **kwargs):        print(kwargs)        print(self.renderer_classes)        return Response('...')views.py
views.py

b. 半自动路由

from django.conf.urls import url, includefrom web.views import s10_genericurlpatterns = [    url(r'^test/$', s10_generic.UserViewSet.as_view({
'get': 'list', 'post': 'create'})), url(r'^test/(?P
\d+)/$', s10_generic.UserViewSet.as_view( {
'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.viewsets import ModelViewSetfrom rest_framework import serializersfrom .. import modelsclass UserSerializer(serializers.ModelSerializer):    class Meta:        model = models.UserInfo        fields = "__all__"class UserViewSet(ModelViewSet):    queryset = models.UserInfo.objects.all()    serializer_class = UserSerializerviews.py
views.py

c. 全自动路由

from django.conf.urls import url, includefrom rest_framework import routersfrom web.views import s10_genericrouter = routers.DefaultRouter()router.register(r'users', s10_generic.UserViewSet)urlpatterns = [    url(r'^', include(router.urls)),]urls.py
urls.py
from rest_framework.viewsets import ModelViewSetfrom rest_framework import serializersfrom .. import modelsclass UserSerializer(serializers.ModelSerializer):    class Meta:        model = models.UserInfo        fields = "__all__"class UserViewSet(ModelViewSet):    queryset = models.UserInfo.objects.all()    serializer_class = UserSerializerviews.py
views.py

 

9. 视图

a. GenericViewSet

from django.conf.urls import url, includefrom web.views.s7_viewset import TestViewurlpatterns = [    url(r'test/', TestView.as_view({
'get':'list'}), name='test'), url(r'detail/(?P
\d+)/', TestView.as_view({
'get':'list'}), name='xxxx'),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework import viewsetsfrom rest_framework.response import Responseclass TestView(viewsets.GenericViewSet):    def list(self, request, *args, **kwargs):        return Response('...')    def add(self, request, *args, **kwargs):        pass    def delete(self, request, *args, **kwargs):        pass    def edit(self, request, *args, **kwargs):        passviews.py
views.py

b. ModelViewSet(自定义URL)

from django.conf.urls import url, includefrom web.views import s10_genericurlpatterns = [    url(r'^test/$', s10_generic.UserViewSet.as_view({
'get': 'list', 'post': 'create'})), url(r'^test/(?P
\d+)/$', s10_generic.UserViewSet.as_view( {
'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})),]urls.py
urls.py
#!/usr/bin/env python# -*- coding:utf-8 -*-from rest_framework.viewsets import ModelViewSetfrom rest_framework import serializersfrom .. import modelsclass UserSerializer(serializers.ModelSerializer):    class Meta:        model = models.UserInfo        fields = "__all__"class UserViewSet(ModelViewSet):    queryset = models.UserInfo.objects.all()    serializer_class = UserSerializerviews.py
views.py

c. ModelViewSet(rest framework路由)

from django.conf.urls import url, includefrom rest_framework import routersfrom app01 import viewsrouter = routers.DefaultRouter()router.register(r'users', views.UserViewSet)router.register(r'groups', views.GroupViewSet)# Wire up our API using automatic URL routing.# Additionally, we include login URLs for the browsable API.urlpatterns = [    url(r'^', include(router.urls)),]urls.py
urls.py
from rest_framework import viewsetsfrom rest_framework import serializersclass UserSerializer(serializers.HyperlinkedModelSerializer):    class Meta:        model = models.User        fields = ('url', 'username', 'email', 'groups')class GroupSerializer(serializers.HyperlinkedModelSerializer):    class Meta:        model = models.Group        fields = ('url', 'name')        class UserViewSet(viewsets.ModelViewSet):    """    API endpoint that allows users to be viewed or edited.    """    queryset = User.objects.all().order_by('-date_joined')    serializer_class = UserSerializerclass GroupViewSet(viewsets.ModelViewSet):    """    API endpoint that allows groups to be viewed or edited.    """    queryset = Group.objects.all()    serializer_class = GroupSerializerviews.py
views.py

 

转载于:https://www.cnblogs.com/mituxiaoshutong/p/9112651.html

你可能感兴趣的文章
我的友情链接
查看>>
shell学习(二)变量
查看>>
Delphi随机数
查看>>
[置顶] webservice系列3---chain
查看>>
hibernate XML配置文件》cfg
查看>>
ExtJS2.0实用简明教程 - ExtJS的组件
查看>>
员工离职原因,只有两点最真实,其他都是扯淡!
查看>>
删除dataGridview中选中的一行或多行
查看>>
使用包ldap3进行Python的LDAP操作
查看>>
#4 Move Find into Model
查看>>
html5 canvas模拟的爆炸效果
查看>>
nodejs中几个excel模块的简单对比
查看>>
面向对象三大特征
查看>>
我的友情链接
查看>>
Ansible学习01-常用模块
查看>>
Java基础学习总结(21)——数组
查看>>
Redis——订阅
查看>>
RAID磁盘阵列笔记
查看>>
CloudStack Site-to-Site & Remote Access ××× 应用案例
查看>>
php过滤提交数据 防止sql注入***(6)
查看>>