drf——drf的使用、APIView源码分析、Request源码分析、Serializer的序列化

系列文章目录

drf
第一章 django web开发模式、api接口、api接口测试工具、restful规范、序列化反序列化、drf安装使用

第二章 drf的使用、APIView源码分析、Request源码分析、Serializer的序列化



一、drf的使用

1.drf容器注册

由于drf实质上是一个app,所以在使用前需要对其进行app注册
settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.Qpp01Config',
    'rest_framework', # 注册drf容器
]

2.模型层建立模型

如下创建对应的模型

class Book(models.Model):
    pname = models.CharField(max_length=20)
    price = models.DecimalField(max_digits=5,decimal_places=2)
    author = models.CharField(max_length=20)
    press = models.CharField(max_length=20)

3.序列化类创建

创建一个serializer.py文件,名字可以自行设定
serializer类中的属性要与模型层的属性对应,可以只对应部分,对应多少序列化时便序列化多少属性

from rest_framework import serializers

class BookSerializer(serializers.Serializer):
    pname = serializers.CharField(max_length=20)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    author = serializers.CharField(max_length=20)
    press = serializers.CharField(max_length=20)

4.视图函数创建

views.py

from rest_framework import views
from rest_framework.response import Response
from rest_framework.request import Request
from .models import Book
from .serializer import BookSerializer


class BookApiView(views.APIView):

    def get(self,request):
        books = Book.objects.all()
        bookSerializer = BookSerializer(instance=books, many=True)
        return Response(bookSerializer.data)

5.开启路由

urls.py

from django.contrib import admin
from django.urls import path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/book/', views.BookApiView.as_view()),
]

在这里插入图片描述

二、APIView源码分析

    def as_view(cls, **initkwargs):
        if isinstance(getattr(cls, 'queryset', None), models.query.QuerySet):
            def force_evaluation():
                raise RuntimeError(
                    'Do not evaluate the `.queryset` attribute directly, '
                    'as the result will be cached and reused between requests. '
                    'Use `.all()` or call `.get_queryset()` instead.'
                )
            cls.queryset._fetch_all = force_evaluation
        view = super().as_view(**initkwargs) #此处APIView继承了django的view的as_view
        view.cls = cls
        view.initkwargs = initkwargs
        return csrf_exempt(view)
        
# 项目启动后as_view()优先执行,返回csrf_exempt(view)



def csrf_exempt(view_func):
    def wrapped_view(*args, **kwargs):
        return view_func(*args, **kwargs)
    wrapped_view.csrf_exempt = True
    return wraps(view_func)(wrapped_view)

## csrf_exempt(view)运行返回wraps(view_func)(wrapped_view)



def wraps(wrapped,
          assigned = WRAPPER_ASSIGNMENTS,
          updated = WRAPPER_UPDATES):

    return partial(update_wrapper, wrapped=wrapped,
                   assigned=assigned, updated=updated)

''' 
wraps(view_func)(wrapped_view)运行后返回partial为
partial(wrapped_view, wrapped=view_func,assigned=assigned, updated=updated)
'''

# 当请求接入时触发dispatch函数
    def dispatch(self, request, *args, **kwargs):
        self.args = args
        self.kwargs = kwargs
        # 此处将django原来的request封装成了新的request
        request = self.initialize_request(request, *args, **kwargs)
        self.request = request
        self.headers = self.default_response_headers  # deprecate?

        try:
        	# 此处有三重验证:权限、认证、频率
            self.initial(request, *args, **kwargs)

            # Get the appropriate handler method
            if request.method.lower() in self.http_method_names:
                handler = getattr(self, request.method.lower(),
                                  self.http_method_not_allowed)
            else:
                handler = self.http_method_not_allowed
			# 对response进行封装,变为了drf自己的response
            response = handler(request, *args, **kwargs)

        except Exception as exc:
            response = self.handle_exception(exc)

        self.response = self.finalize_response(request, response, *args, **kwargs)
        return self.response



三、Request源码分析

class Request:
    """
    Wrapper allowing to enhance a standard `HttpRequest` instance.

    Kwargs:
        - request(HttpRequest). The original request instance.
        - parsers(list/tuple). The parsers to use for parsing the
          request content.
        - authenticators(list/tuple). The authenticators used to try
          authenticating the request's user.
    """

    def __init__(self, request, parsers=None, authenticators=None,
                 negotiator=None, parser_context=None):
        assert isinstance(request, HttpRequest), (
            .format(request.__class__.__module__, request.__class__.__name__)
        )
		#将原来的request放入_request中
        self._request = request
        # 从django的request中获取数据到drf的request
        if self.parser_context is None:
            self.parser_context = {}
        self.parser_context['request'] = self
        self.parser_context['encoding'] = request.encoding or settings.DEFAULT_CHARSET
        force_user = getattr(request, '_force_auth_user', None)
        force_token = getattr(request, '_force_auth_token', None)

四、serializer的序列化

创建一个serializer.py文件,名字可以自行设定
serializer类中的属性要与模型层的属性对应,可以只对应部分,对应多少序列化时便序列化多少属性

from rest_framework import serializers

class BookSerializer(serializers.Serializer):
    pname = serializers.CharField(max_length=20)
    price = serializers.DecimalField(max_digits=5, decimal_places=2)
    author = serializers.CharField(max_length=20)
    press = serializers.CharField(max_length=20)

序列化:

from django.shortcuts import render
from rest_framework import views
from rest_framework.response import Response
from rest_framework.request import Request
from .models import Book
from .serializer import BookSerializer

# Create your views here.

class BookApiView(views.APIView):

    def get(self,request):
    	#查询数据
        books = Book.objects.all()
        #将数据序列化
        bookSerializer = BookSerializer(instance=books, many=True)
        return Response(bookSerializer.data)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值