五大模块(视图,路由,解析,响应,版本控制)

面向对象封装

面向对象封装导入

# 面向对象的封装:
# 1.将子类共有的方法抽离形成父类
# 2.子类使用共有方法,使用的是父类方法
# 3.共有方法中的资源,在子类使用方法时,获取的是子类资源
class MyCls:
    name = None
    @classmethod
    def test(cls):
        print(cls.name)

class ACls(MyCls):
    name = "ACls"
    # @classmethod
    # def test(cls):
    #     print(cls.name)

class BCls(MyCls):
    name = "BCls"
    # @classmethod
    # def test(cls):
    #     print(cls.name)

ACls.test()
BCls.test()
面向对象封装导入

 

 

drf视图层面向对象封装应用

# drf已经做了 CBV 的面向对象封装,且还做了一步精髓之笔,重写了as_view()
class GetListCls: pass # get_list
class PostOneCls: pass # post_one
class GetOneCls: pass # get_one
class PutOneCls: pass # put_one
class DeleteOneCls: pass # delete_one

# get_list | post_one | get_one | put_one | delete_one
class MyCls(GetListCls, PostOneCls, GetOneCls, PutOneCls, DeleteOneCls): pass

# get_list | post_one 
class Books(GetListCls, PostOneCls): pass
# get_list | post_one | get_one | put_one | delete_one
class BookView(MyCls): pass
# get_list | post_one | get_one | put_one | delete_one
class AuthorView(MyCls): pass
drf视图层面向对象封装应用

 

 

基础的五大接口:基础

数据准备

# settings.py
INSTALLED_APPS = [
    # ...
    'rest_framework',
]

# models.py 手动形成数据
class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    author = models.ManyToManyField(to='Author', db_constraint=False)

class Author(models.Model):
    name = models.CharField(max_length=32)
    author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.SET_NULL, null=True, db_constraint=False)

class AuthorDetail(models.Model):
    age = models.IntegerField()
    telephone = models.CharField(max_length=32)
    
# objson.py
from rest_framework import serializers
from app import models
class AuthorDetailJson(serializers.ModelSerializer):
    class Meta:
        model = models.AuthorDetail
        fields = '__all__'

class AuthorJson(serializers.ModelSerializer):
    class Meta:
        model = models.Author
        fields = '__all__' 

class BookJson(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = '__all__'
        
# urls.py
from app import views
urlpatterns = [
    # ...
    url(r'^books/', views.Books.as_view()),
    url(r'^book/(?P<pk>\d+)/', views.Book.as_view()),
]
数据准备

 

 

五大接口

# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from app import models, objson
class Books(APIView):
    # 请求地址:/books/
    def get(self, request, *args, **kwargs):
        book_list = models.Book.objects.all()
        book_data = objson.BookJson(book_list, many=True).data
        return Response({
            'status': 0,
            'msg': 'ok',
            'results': book_data
        })

    # 请求地址:/books/  参数:{"name": "红楼梦","price": "66.66","author": [1]}
    def post(self, request, *args, **kwargs):
        book_json = objson.BookJson(data=request.data)
        if book_json.is_valid():
            book_json.save()
            return Response({
                'status': 0,
                'msg': 'ok',
                'results': book_json.data
            })
        return Response({
            'status': 1,
            'msg': book_json.errors,
        })


class Book(APIView):
    # 请求地址:/book/1/
    def get(self, request, pk, *args, **kwargs):
        book = models.Book.objects.filter(pk=pk).first()
        book_data = objson.BookJson(book).data
        return Response({
            'status': 0,
            'msg': 'ok',
            'results': book_data
        })

    # 请求地址:/book/2/ 参数:{"name": "红楼梦","price": "88.88","author": [1]}
    def put(self, request, pk, *args, **kwargs):
        book = models.Book.objects.filter(pk=pk).first()
        book_json = objson.BookJson(data=request.data, instance=book)
        if book_json.is_valid():
            book_json.save()
            return Response({
                'status': 0,
                'msg': 'ok',
                'results': book_json.data
            })
        return Response({
            'status': 1,
            'msg': book_json.errors,
        })

    # 请求地址:/book/2/
    def delete(self, request, pk, *args, **kwargs):
        deleted, _ = models.Book.objects.filter(pk=pk).delete()
        if deleted != 0:
            return Response({
                'status': 2,
                'msg': 'delete success',
            })
        return Response({
            'status': 1,
            'msg': 'delete failed',
        })
五大接口

 

 

五大接口的基础整合:过渡

# views.py
from rest_framework.viewsets import ModelViewSet
from app import models, objson
class Books(ModelViewSet):
    queryset = models.Book.objects
    serializer_class = objson.BookJson

class Book(ModelViewSet):
    queryset = models.Book.objects
    serializer_class = objson.BookJson
    lookup_field = 'pk'
    
# urls.py
from app import views
urlpatterns = [
    url(r'^books/', views.Books.as_view({'get': 'list', 'post': 'create'})),
    url(r'^book/(?P<pk>\d+)/', views.Book.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
]

# 解读:
"""
ModelViewSet继承:五大接口的Mixin,GenericViewSet
    -- 五大接口的Mixin:
        -- 分别提供 get_list(list) | post_one(create) | get_one(retrieve) | put_one(update) | delete_one(destroy)
        
    -- GenericViewSet: 
        -- 继承:ViewSetMixin, GenericAPIView
            -- ViewSetMixin:重写as_view(): 解析路由 as_view({'get': 'list', 'post': 'create'}))
            -- GenericAPIView:提供基础的 APIView,拥有请求方式
"""
五大接口的基础整合:过渡

 

 

项目开发基于drf的cbv设计:重点

# views.py
from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from app import models, objson

# 可以将于Book有关的所有操作函数都放在改CBV中,任何在路由层完成as_view("请求方式": "处理方法")分发
class BookView(ModelViewSet):
    # 如果需要使用基础(没有任何业务逻辑)的五大接口
    queryset = models.Book.objects  # 数据
    serializer_class = objson.BookJson # 序列化组件
    lookup_field = 'pk'  # 有名分组key

    # 实际开发的业务逻辑远远远超出五大接口的基础逻辑范围
    # 自定义n个处理数据的函数
    def get_book_by_id(self, request, id, *args, **kwargs):
        book = models.Book.objects.filter(pk=id).first()
        book_data = objson.BookJson(book).data
        return Response({
            'status': 0,
            'msg': 'ok',
            'results': book_data
        })

    def get_n(self, request, *args, **kwargs):
        return Response({
            'status': 0,
            'msg': 'get_n response method',
        })

# urls.py
from app import views
urlpatterns = [
    # url(r'^books/', views.BookView.as_view({'get': 'list', 'post': 'create'})),
    # url(r'^book/(?P<pk>\d+)/', views.BookView.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'})),
    url(r'^book/(?P<id>\d+)/', views.BookView.as_view({'get': 'get_book_by_id'})),
    url(r'^book_n/', views.BookView.as_view({'get': 'get_n'})),
]
项目开发基于drf的cbv设计:重点

 

 

路由模块

from app import views
urlpatterns = [
    # CBV传统
    url(r'^books/', views.Books.as_view()),
]

urlpatterns = [
    # CBV路由的函数分发
    url(r'^books/', views.BookView.as_view({'get': 'get_list'})),
]
路由模块

 

 

解析模块

# views.py

# 解析模块:form-data(MultiPartParser)  from-urlencoded(FormParser)  json(JSONParser)
from rest_framework.viewsets import ModelViewSet
from rest_framework.parsers import MultiPartParser, FormParser, JSONParser
from rest_framework.response import Response
class TestParsers(ModelViewSet):
    # 插拔式:选择性定制解析模块
    # 配置用户不同方式提交数据,服务器能否提供解析
    parser_classes = [MultiPartParser, FormParser, JSONParser]  # 局部配置
    def post(self, request, *args, **kwargs):
        return Response({
            'status': 0,
            'msg': 'TestParsers',
            'results': request.data
        })
    
# settings.py
# 全局配置
REST_FRAMEWORK = {
    'DEFAULT_PARSER_CLASSES': (
        'rest_framework.parsers.JSONParser',
        'rest_framework.parsers.FormParser',
        'rest_framework.parsers.MultiPartParser',
    )
}

# urls.py
url(r'^parsers/', views.TestParsers.as_view({'post': 'post'})),
解析模块

 

 

响应模块

# views.py

# 响应模块:
from rest_framework.viewsets import ModelViewSet
from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
from rest_framework.response import Response
class TestRenderers(ModelViewSet):
    # 插拔式:选择性定制响应模块
    # 配置服务器提供的不同响应数据的方式
    # renderer_classes = [JSONRenderer]
    def get(self, request, *args, **kwargs):
        return Response({
            'status': 0,
            'msg': 'TestRenderers',
        })
    
# settings.py
# 全局配置
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': (
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',
    ),
}

# urls.py
url(r'^renderers/', views.TestRenderers.as_view({'get': 'get'})),
响应模块

 

 

版本控制模块

基础配置

REST_FRAMEWORK = {
    # 默认版本
    'DEFAULT_VERSION': 'v1',
    # 现存版本
    'ALLOWED_VERSIONS': ['v1', 'v2'],
    # url的参数key
    'VERSION_PARAM': 'version',
}
基础配置

 

 

通过请求参数完成版本配置

# api.site.com/versioning/?version=v1 | api.site.com/versioning/?version=v2
#         -- QueryParameterVersioning
#         -- url(r'^versioning/', views.TestVersioning.as_view({'get': 'get'})),
#        -- 请求:/versioning/?version=v1  |  /versioning/?version=v2

from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from rest_framework.versioning import QueryParameterVersioning
class TestVersioning(ModelViewSet):
    versioning_class = QueryParameterVersioning
    def get(self, request, *args, **kwargs):
        # print(request.version)
        # print(request.versioning_scheme)
        if request.version == 'v1':
            print('v1版本的业务逻辑')
        elif request.version == 'v2':
            print('v2版本的业务逻辑')

        return Response({
            'status': 0,
            'msg': 'TestVersioning',
            'version': request.version
        })
通过请求参数完成版本配置

 

 

通过请求url完成版本配置: 常用

# api.site.com/v1/versioning/ | api.site.com/v2/versioning/
#         -- URLPathVersioning
#         -- url(r'^(?P<version>(v1|v2)/versioning/', views.TestVersioning.as_view({'get': 'get'})),
#        -- 请求:v1/versioning/ |  v2/versioning/

from rest_framework.viewsets import ModelViewSet
from rest_framework.response import Response
from rest_framework.versioning import URLPathVersioning
class TestVersioning(ModelViewSet):
    versioning_class = URLPathVersioning
    def get(self, request, *args, **kwargs):
        if request.version == 'v1':
            print('v1版本的业务逻辑')
        elif request.version == 'v2':
            print('v2版本的业务逻辑')

        return Response({
            'status': 0,
            'msg': 'TestVersioning',
            'version': request.version
        })
通过请求url完成版本配置: 常用

 

posted @ 2019-08-05 09:57  -Rye-  阅读(355)  评论(0)    收藏  举报