Django REST Framework 数码宝贝 - 3步进化 - 混合类 -->
读了我这篇博客, 你会刷新对面对对象的认知, 之前的面对对象都是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
总结:
建议用以下两种方式
Django REST Framework 数码宝贝 - 3步进化 - 混合类 -->的更多相关文章
- [Django REST framework - 视图组件之视图基类、视图扩展类、视图子类、视图集]
[Django REST framework - 视图组件之视图基类.视图扩展类.视图子类.视图集] 视图继承关系 详图见文章末尾 视图组件可点我查看 两个视图基类:APIView.GenericAP ...
- DRF(Django REST Framework)框架
目录 一.DRF中的Request 二.前戏: 关于面向对象的继承 三.初级版本 1. settings.py文件 -- 注册app 2. models.py文件 -- 创建表 3. admin.py ...
- Django REST framework基础:视图和路由
DRF中的Request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别于Dj ...
- python 全栈开发,Day96(Django REST framework 视图,django logging配置,django-debug-toolbar使用指南)
昨日内容回顾 1. Serializer(序列化) 1. ORM对应的query_set和ORM对象转换成JSON格式的数据 1. 在序列化类中定义自定义的字段:SerializerMethodFie ...
- Django REST framework - 权限和限制
目录 Django REST framework 权限和限制 (你能干什么) 设置权限的方法 案例 第一步: 定义一个权限类 第二步: 使用 视图级别 全局级别设置 --- 限制 (你一分钟能干多少次 ...
- Django REST framework完全入门
Django REST framework 一个强大灵活的Django工具包,提供了便捷的 REST API 开发框架 我们用传统的django也可以实现REST风格的api,但是顶不住Django ...
- 03 Django REST Framework 视图和路由
01-DRF中的request 在Django REST Framework中内置的Request类扩展了Django中的Request类,实现了很多方便的功能--如请求数据解析和认证等. 比如,区别 ...
- 利用 Django REST framework 编写 RESTful API
利用 Django REST framework 编写 RESTful API Updateat 2015/12/3: 增加 filter 最近在玩 Django,不得不说 rest_framewor ...
- Django REST Framework学习——Android使用REST方法访问Diango
本文更应该叫做Android如何模拟浏览器访问Django服务器后台. 环境为: Android通过HttpClient访问服务器,从Django中获取json数据,解析显示在UI界面上. 问题为: ...
随机推荐
- ThinkPHP3.1.3分表状态时候的自动验证的代码BUG
问题描述 ThinkPHP3.1.3 当使用TP的分库分表后 有些地方需要使用Model自动验证create,当验证唯一性unique会出现BUG, 具体描述 因为自动验证检测唯一性会使用隐式的使用f ...
- 《你又怎么了我错了行了吧》【Alpha】Scrum meeting 5
第五天 日期:2019/6/18 前言: 第5次会议在女生宿舍召开 冲刺第5天,对所有工作做了总结.继续完善编码工作. 1.1 今日完成任务情况以及明天任务安排 姓名 当前阶段任务 下一阶段任务 刘 ...
- BA-通讯总线-百通1419a和9841
百通1419A线缆的简单介绍: Belden1419A- Belden电缆线1419A 多股导体—低容计算机电缆 FOR EIA RS-232/422 Belden 1419A是24 AWG(7*32 ...
- [C++设计模式] iterator 迭代器模式
迭代器模式定义:提供一种方法顺序訪问一个聚合对象中各个元素,而又不须要暴露该对象. 迭代器分内部迭代器和外部迭代器.内部迭代器与对象耦合紧密,不推荐使用. 外部迭代器与聚合容器的内部对象松耦合,推荐使 ...
- Geeks - Range Minimum Query RMQ范围最小值查询
使用线段树预处理.能够使得查询RMQ时间效率在O(lgn). 线段树是记录某范围内的最小值. 标准的线段树应用. Geeks上仅仅有两道线段树的题目了.并且没有讲到pushUp和pushDown操作. ...
- 项目部署在windows下的tomcat里
打包放在webapps 目录下,web的改成ROOT ok!!!
- Win+X
Win+X 方便的快捷键,可以快速使用命令行和运行!
- 蓝桥杯--算法提高 排列数 (简单dfs)
算法提高 排列数 时间限制:1.0s 内存限制:256.0MB 问题描述 0.1.2三个数字的全排列有六种,按照字母序排列如下: 012.021.102.120.201.210 输入 ...
- 【转】iOS 设置APP的名称(浅述APP版本国际化与本地化)
原文网址:http://www.jianshu.com/p/a3a70f0398c4 前言 App的名字设置方式有很多种,如果在App打包上线时不做修改,最终App的名字就是Xcode在建立工程时的名 ...
- 关于volatile的一些思考C++
在c++中,volatile用与修饰容易变动的变量,通常用于多线程的标志,编译器会存在代码优化,假如在同一个大括号中没有修改这么一个参数,那么编译器很可能在读取这个值的时候使用的是快取的方法,即将这个 ...