DRF introduced, DRF project development, project DRF view class source code parsing of dispatch

A, DRF introduced

1. What is the DRF

  • DRF is a plug-django framework or django package is a tool for building Web interfaces Restful background.

2. Why DRF

The reason (1) using the DRF

  • In general:
    • Since django model has built-in CBV, why re-learn a DRF to build our project yet. Because drf offers more features (such as the three major validation, Restful interface, etc.), its model than django CBV CBV model comes easier to use, function better for large projects, higher development efficiency.
  • Fine for:
    • Start with the size of the project point of view, if the project is small (a few simple interface and page), with FBV enough of Django, simple, low-cost learning; in large-scale projects, people involved in the project, recommended DRF, although learning route is longer, but in the long run, efficiency and norms are higher
    • Another reason for us to reuse DRF is the project division of refinement, through the introduction of front-end team, will optimize separated into front and back of the original template straight out of the way, the page rendering data provided by Restful interface front-end engineering, the back-end services of the code decoupled, higher development efficiency

(2) standing on a developer's point terms with the benefits of the DRF (temporary list so much)

  1. Installed Django project, you will be able to provide a Restful interfaces in Django
  2. You can browse your own which provides the API in a Web page, and these can be tested through this API page
  3. You do not have to write your own set of interfaces authentication code
  4. You do not write a lot of CRUD interfaces themselves, simple configuration can
  5. You do not have to write yourself a lot of conditions query interface, simple configuration can
  6. You do not write their own background paging logic, simple configuration can
  7. You do not write interface logic limiting himself to a simple configuration
  8. You do not have to write a variety of simple parameter validation logic on their own, simple configuration can
  9. You do not have registered their various routing, simple configuration can
  10. You do not have permission to write to the control logic in the business logic

Second, the back-end development project with DRF

  • After download and install drf is, in our new django project, registered drf, then writing in line with restful routing interface specification, written in the views of CBV model drf file (using the view class drf are inherited APIView class).

  • Project examples:

'''
drf框架安装:
    1)drf是Django的插件,所以要提前按照Django框架
    2)终端中使用命令:python pip install djangorestframework
    3)使用drf时,要在settings中注册
'''
# settings文件中:
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',

    # drf一定需要注册
    'rest_framework',
    # 应用程序注册
    'api',
]


# urls文件中:

from django.conf.urls import url
from . import views

urlpatterns = [
    # url(r'^v1/books/$', views.BookView.as_view()),
    # url(r'^v1/books/(?P<pk>\d+)/$', views.BookView.as_view()),
    #
    # url(r'^v2/books/$', views.BookAPIView.as_view()),
    # url(r'^v2/books/(?P<pk>\d+)/$', views.BookAPIView.as_view()),

    url(r'^books/$', views.BookAPIView.as_view()),
    url(r'^books/(?P<pk>\d+)/$', views.BookAPIView.as_view()),
]

# views文件中:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.parsers import JSONParser, FormParser, MultiPartParser
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
from rest_framework import status

class BookAPIView(APIView):
    # 局部配置解析类:只适用当前视图类
    parser_classes = [JSONParser, FormParser, MultiPartParser]
    # 局部配置渲染类:只适用当前视图类
    renderer_classes = [JSONRenderer, BrowsableAPIRenderer]

    def get(self, request, *args, **kwargs):
        # a
        response = Response(
            data={
                'msg': 'apiview get ok'
            },
            status=status.HTTP_404_NOT_FOUND,
        )
        print(response.data)
        return response
    def post(self, request, *args, **kwargs):
        print(request._request.method)  # 在内部将wsgi的request赋值给request._request
        print(request.method)  # 就是通过__getattr__走的是request._request.method
        print(request.query_params)  # 走的是方法属性,就是给request._request.GET重新命名
        print(request.data)  # 走的是方法属性,值依赖于request._full_data

        return Response({
            'msg': 'apiview post ok'
        })

Three, APIView request lifecycle

  • APIView is drf view class inherited class, the class is offered drf
# APIView请求生命周期

'''
APIView的as_view(局部禁用csrf校验) => 
走父级的as_view调用dispatch分发请求 => 
APIView自己重写了dispatch,使用自己完成分发 => 
分发前完成request二次封装、数据解析 => 
三大认证 => 
请求的实际响应(自己的视图类的处理分发) => 
出现了异常,就会交给异常模块处理异常 => 
响应模块完成响应、渲染模块可以json或浏览器两种方式渲染
'''

Fourth, the source of the dispatch of the method

  • The method of action is the source dispatch class for different ways of distributing the request to the corresponding final results returned in response to the leading end.
  • Source dispatch entry is equivalent to the view layer. Many of its internal service logic comprising

1. dispatch function module

(1) requesting module

'''
drf源码的dispatch中对wsgi的request进行了二次封装:

    用新的request._request = wsgi的request

    用新的request.query_params = wsgi的request.GET

    用新的request.data = request._full_data    _full_data里利用解析模块获取的是wsgi的request.POST 和 request.body 和异常信息 等数据

    在外部访问新的request.属性,源码中通过在__getattr__方法中的利用反射,访问新的request.属性会先去wsgi的request中查找,若没有,再去新的request中找
    
'''

(2) parsing module

# 局部配置:(在需要配置的视图类中定义,只对当前配置的视图类有作用)
parser_classes = [JSONParser, FormParser, MultiPartParser]

# 全局配置:(在settings文件中配置,对全部视图类都有作用)

REST_FRAMEWORK = {
    # 全局配置解析类:适用于所有视图类
    'DEFAULT_PARSER_CLASSES': [
        # 'rest_framework.parsers.JSONParser',
        # 'rest_framework.parsers.FormParser',
        # 'rest_framework.parsers.MultiPartParser'
    ],
    # 全局配置渲染类:适用于所有视图类
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        # 'rest_framework.renderers.BrowsableAPIRenderer',  # 上线后尽量关闭
    ],
    # 异常模块:异常处理函数
    # 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
    'EXCEPTION_HANDLER': 'api.exception.exception_handler',
}
    

(3) response module

Respose(data=常量|列表|字典, status=网络状态码)

# 网络状态码的数字是后端自定义的,但是数字对应的状态信息是http协议规定好了的,不能修改,当网络状态码到前端中,其状态信息会自动展示出来。

(4) rendering module

  • Depending on the
# 局部配置:(在需要配置的视图类中定义,只对当前配置的视图类有作用)
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]  # 在实际开发者,不需要 BrowsableAPIRenderer 参数,因为这个参数会让浏览器显示一个页面,其包含了当前项目的信息。我们只需要用JSONRenderer让前端只展示数据即可


# 全局配置:(在settings文件中配置,对全部视图类都有作用)
REST_FRAMEWORK = {
    # 全局配置解析类:适用于所有视图类
    'DEFAULT_PARSER_CLASSES': [
        # 'rest_framework.parsers.JSONParser',
        # 'rest_framework.parsers.FormParser',
        # 'rest_framework.parsers.MultiPartParser'
    ],
    # 全局配置渲染类:适用于所有视图类
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        # 'rest_framework.renderers.BrowsableAPIRenderer',  # 上线后尽量关闭
    ],
    # 异常模块:异常处理函数
    # 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
    'EXCEPTION_HANDLER': 'api.exception.exception_handler',  # api.exception中api是app名,exception是我们新建的异常模块文件名
}

(5) an abnormal module

  • DRF's own abnormal module will only catch exceptions front end, back-end exceptions need to capture our own, so we need to rewrite their own abnormal module, add functionality to capture back-end anomaly original exception module.

  • Rewrite module abnormalities, in two steps


# 1. settings中全局配置:*********************************************

REST_FRAMEWORK = {
    # 全局配置解析类:适用于所有视图类
    'DEFAULT_PARSER_CLASSES': [
        # 'rest_framework.parsers.JSONParser',
        # 'rest_framework.parsers.FormParser',
        # 'rest_framework.parsers.MultiPartParser'
    ],
    # 全局配置渲染类:适用于所有视图类
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        # 'rest_framework.renderers.BrowsableAPIRenderer',  # 上线后尽量关闭
    ],
    # 异常模块:异常处理函数
    # 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler',
    'EXCEPTION_HANDLER': 'api.exception.exception_handler',
}

# 2. 在app文件夹中新建一个py文件,重写exception_handler方法*********************************************

# 一定要在settings文件中将异常模块配置成自己的异常处理函数
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response

# 先交给drf处理客户端异常,如果结果response为None代表服务器异常,自己处理
# 最终一定要在日志文件中记录异常现象
def exception_handler(exc, context):  # 重写异常模块exception_handler
    response = drf_exception_handler(exc, context)  # 利用原模块继续捕捉前端异常
    detail = '%s - %s - %s' % (context.get('view'), context.get('request').method, exc)
    if not response:  # 服务端错误
        response =  Response({'detail': detail})
    else:
        response.data = {'detail': detail}

    # 核心:要将response.data.get('detail')信息记录到日志文件
    # logger.waring(response.data.get('detail'))

    return response

Guess you like

Origin www.cnblogs.com/Mcoming/p/12093446.html