读了我这篇博客, 你会刷新对面对对象的认知, 之前的面对对象都是LJ~~~
表结构
class Publisher(models.Model): name = models.CharField(max_length=32) def __str__(self): return self.name class Author(models.Model): name = models.CharField(max_length=32) def __str__(self): return self.name class Book(models.Model): title = models.CharField(max_length=32) pub_date = models.DateField() CHOICES = ((1, ‘Python‘), (2, ‘Go‘), (3, ‘linux‘)) category = models.IntegerField(choices=CHOICES) publisher = models.ForeignKey(to=‘Publisher‘, on_delete=models.CASCADE) authors = models.ManyToManyField(to=‘Author‘) def __str__(self): return self.title
原路由:
urlpatterns = [ url(r‘^admin/‘, admin.site.urls), url(r‘^books/$‘, views.BookListView.as_view()), url(r‘book/(?P<pk>\d+)$‘, views.BookDetailView.as_view()), url(r‘^publishers/$‘, views.PublisherView.as_view()), url(r‘publishers/(?P<pk>\d+)$‘, views.PublisherDetailView.as_view()), ]
原始版:
获取出版社信息
# 获取出版社信息 class PublisherView(APIView): """使用Django REST framework 内置的序列化""" def get(self,request): """Json格式返回所有的书籍信息""" queryset = models.Publisher.objects.all() ser_obj = ModelPublisherSerlizer(queryset, many=True) return Response(ser_obj.data) def post(self, request): ser_obj = ModelPublisherSerlizer(data=request.data) if ser_obj: ser_obj.save() return Response(‘ok‘) else: return Response(ser_obj.errors)
获取具体某个出版社信息 查 改 删 -- >
# 获取具体某个出版社信息 class PublisherDetailView(APIView): def get(self,pk): publisher_ob = models.Publisher.objects.filter(pk=pk) publisher_obj = models.Publisher.objects.filter(pk=pk).first() print("publisher_ob", publisher_ob, "publisher_obj", publisher_obj) if publisher_obj: ser_obj = ModelPublisherSerlizer(publisher_obj) return Response(ser_obj.data) else: return Response("无效的id") def put(self, request, pk): publisher_obj = models.Publisher.objects.filter(pk=pk).first() if publisher_obj: ser_obj = ModelPublisherSerlizer(instance=publisher_obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.data) else: return Response(ser_obj.errors) else: return Response("没有这本书") def delete(self,pk): publisher_obj = models.Publisher.objects.filter(pk=pk) if publisher_obj: publisher_obj.delete() return Response("删除成功") else: return Response("没有这本书")
进化版:
把出版社相关信息封装起来
class CemericView(APIView): """视图中可能用到的配置和方法封装起来""" queryset = None serializer_class = None def get_queryset(self): # 让每次请求来的时候都先查一次数据 return self.queryset.all() class ListMinxin(object): def get(self, request): queryset = self.get_queryset() ser_obj = self.serializer_class(queryset, many=True) return Response(ser_obj.data) class CreateMixin(object): def post(self, request): ser_obj = self.serializer_class(data=request.data) if ser_obj: ser_obj.save() return Response(‘ok‘) else: return Response(ser_obj.errors) # 获取出版社信息 class PublisherView(CemericView, ListMinxin, CreateMixin): queryset = models.Publisher.objects.all() serializer_class = ModelPublisherSerlizer
超级进化版:
把某个出版社的信息也封装起来
class GemericView(APIView): """视图中可能用到的配置和方法封装起来""" queryset = None serializer_class = None def get_queryset(self): # 让每次请求来的时候都先查一次数据 return self.queryset.all() def get_obj(self, request, pk, *args, **kwargs): return self.get_queryset().filter(pk=pk).filter(pk=pk).first() class ListMinxin(object): def get(self, request): queryset = self.get_queryset() ser_obj = self.serializer_class(queryset, many=True) return Response(ser_obj.data) class CreateMixin(object): def post(self, request): ser_obj = self.serializer_class(data=request.data) if ser_obj.is_valid(): ser_obj.save() return Response(‘ok‘) else: return Response(ser_obj.errors) # 获取出版社信息 class PublisherView(GemericView, ListMinxin, CreateMixin): queryset = models.Publisher.objects.all() serializer_class = ModelPublisherSerlizer class RetrieveMixin(object): def get(self, request, pk, *args, **kwargs): obj = self.get_obj(request, pk, *args, **kwargs) if obj: ser_obj = self.serializer_class(obj) return Response(ser_obj.data) else: return Response("无效的id") class UpdateMixin(object): def put(self, request, pk, *args, **kwargs): obj = self.get_obj(request, pk, *args, **kwargs) if obj: ser_obj = ModelPublisherSerlizer(instance=obj, data=request.data, partial=True) if ser_obj.is_valid(): ser_obj.save() return Response(ser_obj.data) else: return Response(ser_obj.errors) else: return Response("没有这本书") class DelMixin(object): def delete(self, request, pk, *args, **kwargs): obj = self.get_obj(request, pk, *args, **kwargs) print(obj) # print(obj.filter(pk = pk)) if obj: obj.delete() return Response("删除成功") else: return Response("没有这本书") # 获取具体某个出版社信息 class PublisherDetailView(GemericView, RetrieveMixin, UpdateMixin, DelMixin): queryset = models.Publisher.objects.all() serializer_class = ModelPublisherSerlizer
如果在写一个api 的话 只需要3行代码,
但是 封装的代码好像有点多, 继承关系有点乱,
其实框架本身提供了内置方法,
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
注意: 单纯的导入 不能成功, 因为 此方法中不是以 get ,post 等命名的, 导致 MVC模型中 as.view(), 找不到 请求的方式, 需要 对 这些方法进行进一步封装
就有了下面的内置方法
from rest_framework.generics import ListCreateAPIView,RetrieveDestroyAPIView #这个包里里面 封装了 各种用于API 开发的浏览器 请求方式, 及组合方式, 直接调用即可
一共 7行 代码解决
from rest_framework.generics import ListCreateAPIView, RetrieveDestroyAPIView # 获取出版社信息 class PublisherView(ListCreateAPIView): queryset = models.Publisher.objects.all() serializer_class = ModelPublisherSerlizer # 获取具体某个出版社信息 class PublisherDetailView(RetrieveDestroyAPIView): queryset = models.Publisher.objects.all() serializer_class = ModelPublisherSerlizer
究极进化版:
上面超级进化版 一张表要写两个视图 定义queryset和serializer_class 重复,
而且 路由也需要重复, 显然, 究极进化是不允许的~~
重写了as_view()
方法,实现了根据请求的方法执行具体的类方法
路由注册的时候,利用actions参数,实现路由的定向分发 而不是简单的 反射
url(r‘authors/$‘, views.AuthorViewSet.as_view(actions={‘get‘: ‘list‘, ‘post‘: ‘create‘})), # 作者列表 url(r‘authors/(?P<pk>\d+)/$‘, views.AuthorViewSet.as_view( actions={‘get‘: ‘retrieve‘, ‘put‘: ‘update‘, ‘delete‘: ‘destroy‘}) ), # 作者详情
路由都重复写两条:
还可以利用内置的DefaultRouter来实现路由的注册
from rest_framework.routers import DefaultRouter router = DefaultRouter() router.register(‘authors‘, views.AuthorViewSet) urlpatterns += router.urls
from rest_framework.viewsets import ModelViewSet class AuthorViewSet(ModelViewSet): """ list() create() retrieve() update() destroy() """ queryset = models.Author.objects.all() serializer_class = AuthorModelSerializer
总结:
建议用以下两种方式
原文地址:https://www.cnblogs.com/konghui/p/10268393.html
时间: 2024-10-10 09:59:15