五大模块(视图,路由,解析,响应,版本控制)
# 面向对象的封装: # 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已经做了 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
# 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,拥有请求方式 """
# 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'})), ]
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 })
# 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 })


浙公网安备 33010602011771号