面向对象封装
面向对象封装导入
# 1.将子类共有的方法抽离形成父类方法 # 2.子类使用共有方法,使用的是父类方法 # 3.共有方法中的资源,在子类使用方法时,获取的是子类资源 class MyClass: name = None @classmethod def test(cls): print(cls.name) class AClass(MyClass): name = "AClass" class BClass(MyClass): name = "BClass" AClass.test() BClass.test()
drf视图层面向对象封装应用
# drf已经做了 CBV的面向对象封装,且还做了一步精髓之笔,重写了as_view() class GetListClass: pass # get_list class PostOneClass: pass # post_one class GetOneCLass: pass # get_one class PutOneClass: pass # put_one class DeleteOneClass: pass # delete_one # get_list | post_one | get_one | put_one | delete_one class MyClass(GetListClass,PostOneClass,GetOneCLass,PutOneClass,DeleteOneClass): pass # get_list | post_one class Books(GetListClass,PostOneClass): pass # get_list | post_one | get_one | put_one | delete_one class BookView(MyClass): pass # get_list | post_one | get_one | put_one | delete_one class AuthorView(MyClass): 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) # objectjson.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()), ]
五大接口
from rest_framework.views import APIView from rest_framework.response import Response from app import models, objectjson class Books(APIView): # 请求地址:/books/ def get(self, request, *args, **kwargs): book_list = models.Book.objects.all() book_data = objectjson.BookJson(book_list, many=True).data return Response({ 'status': 0, 'message': 'ok', 'results': book_data }) # 请求地址:/books/ 参数::{"name": "红楼梦","price": "66.66","author": [1]} def post(self, request, *args, **kwargs): book_json = objectjson.BookJson(data=request.data) if book_json.is_valid(): book_json.save() return Response({ 'status': 0, 'message': 'ok', 'results': book_json.data }) class Book(APIView): # 请求地址:/book/1/ def get(self, request, pk, *args, **kwargs): book = models.Book.objects.filter(pk=pk).first() book_data = objectjson.BookJson(book).data return Response({ 'status': 0, 'message': '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 = objectjson.BookJson(data=request.data, instance=book) if book_json.is_valid(): book_json.save() return Response({ 'status': 0, 'message': 'ok', 'results': book_json.data }) return Response({ 'status': 0, 'message': 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, 'message': 'delete success' }) return Response({ 'status': 1, 'message': 'delete failed' })
五大接口的基础整合:过渡
# views.py from rest_framework.viewsets import ModelViewSet from app import models, objectjson class Books(ModelViewSet): queryset = models.Book.objects serializer_class = objectjson.BookJson class Book(ModelViewSet): queryset = models.Book.objects serializer_class = objectjson.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, generics.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, objectjson # 可以将于Book有关的所有操作函数都放在该CBV中,任何在路由层完成as_view("请求方式":"处理方法")分发 class BookView(ModelViewSet): # 如果需要使用基础(没有任何业务逻辑)的五大接口 queryset = models.Book.objects serializer_class = objectjson.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 = objectjson.BookJson(book).data return Response({ 'status': 0, 'message': 'ok', 'results': book_data }) # urls.py urlpatterns = [ url(r'^book/(?P<id>\d+)/', views.BookView.as_view({'get': 'get_book_by_id'})), ]
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 TestParser(ModelViewSet): # 插拔式:选择性定制解析 # 配置用户不同方式提交数据,服务器能否提供解析 parser_classes = [MultiPartParser, FormParser, JSONParser] # 局部配置即parser_classes=[]在列表中填哪个这个类就解析什么 def post(self, request, *args, **kwargs): return Response({ 'status': 0, 'message': 'TestParser', 'results': request.data }) REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': ( 'rest_framework.parsers.JSONParser', 'rest_framework.parsers.FormParser', 'rest_framework.parsers.MultiPartParser' ) } # 注释哪个就在全局不使用哪个上传数据的格式 # urls.py urlpatterns = [ url(r'^parsers/', views.TestParser.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 TestParser(ModelViewSet): # 插拔式:选择性定制相应模块 # 配置服务器提供的不同相应数据的方式 # renderer_classes = [JSONRenderer]# 局部配置需要哪个写哪个 def get(self, request, *args, **kwargs): return Response({ 'status': 0, 'message': 'TestParser' }) # settings.py # 全局配置 REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': ( 'rest_framework.renderers.JSONRenderer', # 'rest_framework.renderers.BrowsableAPIRenderer', ) } # 当别人在浏览器中访问你的路由,会知道你用了drf模块,在实际开发中一般禁用BrowsableAPIRenderer。 # urls.py urlpatterns = [ url(r'^parsers/', views.TestParser.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=v1 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, 'message': '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'})), 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): print(request.version) print(request.versioning_scheme) if request.version == 'v1': print('v1版本的业务逻辑') elif request.version == 'v2': print('v2版本的业务逻辑') return Response({ 'status': 0, 'message': 'TestVersioning', 'version': request.version })