rest_framework中视图相关
模型类的定义
# 定义图书模型类BookInfo
class BookInfo(models.Model):
btitle = models.CharField(max_length=20, verbose_name='名称')
bpub_date = models.DateField(verbose_name='发布日期')
bread = models.IntegerField(default=0, verbose_name='阅读量')
bcomment = models.IntegerField(default=0, verbose_name='评论量')
is_delete = models.BooleanField(default=False, verbose_name='逻辑删除') class Meta:
db_table = 'tb_books' # 指明数据库表名
verbose_name = '图书' # 在admin站点中显示的名称
verbose_name_plural = verbose_name # 显示的复数名称 def __str__(self):
"""定义每个数据对象的显示信息"""
return self.btitle
定义一个序列化器
from rest_framework import serializers # 引入类 class BookInfoSerializer(serializers.Serializer):
""" 图书列表序列化器"""
id = serializers.IntegerField(label="ID", read_only=True)
btitle = serializers.CharField(label="名称", max_length=20)
bpub_date = serializers.DateField(label='发布日期', required=False)
bread = serializers.IntegerField(label='阅读量', required=False)
bcomment = serializers.IntegerField(label='评论量', required=False)
is_delete = serializers.BooleanField(label='逻辑删除', required=False)
heroinfo_set = serializers.PrimaryKeyRelatedField(read_only=True, many=True) # 新增 def create(self, validated_data):
"""新建"""
return BookInfo.objects.create(**validated_data) def update(self, instance, validated_data):
"""更新,instance为要更新的对象实例"""
instance.btitle = validated_data.get('btitle', instance.btitle)
instance.bpub_date = validated_data.get('bpub_date', instance.bpub_date)
instance.bread = validated_data.get('bread', instance.bread)
instance.bcomment = validated_data.get('bcomment', instance.bcomment)
instance.save()
return instance
django本身的View类来构建一个RESTful风格的API接口的开发;
import json
from django.forms import model_to_dict
from django.http import JsonResponse
from django.shortcuts import HttpResponse
from django.views import View
from rest_framework.viewsets import ModelViewSet from .models import BookInfo class BooksAPIView(View):
def get(self, request):
"""
查询所有图书
:param request:
:return:
"""
queryset = BookInfo.objects.all().values()
book_list = []
book_list = list(queryset) return JsonResponse(book_list, safe=False) def post(self, request):
"""
新增图书
:param request:
:return:
"""
json_bytes = request.body
json_str = json_bytes.decode()
book_dict = json.loads(json_str)
book = BookInfo.objects.create(
**book_dict
) return JsonResponse({
"id": book.id,
"btitle": book.btitle,
'bpub_date': book.bpub_date,
'bread': book.bread,
'bcomment': book.bcomment,
}, status=201) class BookAPIView(View):
"""
获取单个图书的信息
""" def get(self, request, pk):
try:
book = BookInfo.objects.get(id=pk)
except Exception as e:
print(e)
return HttpResponse(status=404) book_dict = model_to_dict(book)
return JsonResponse(book_dict) def put(self, request, pk):
"""
修改图书信息
:param request:
:param pk:
:return:
"""
try:
book = BookInfo.objects.get(id=pk)
except Exception as e:
print(e)
return HttpResponse(status=404) # 校验参数 json_bytes = request.body
json_str = json_bytes.decode()
book_dict = json.loads(json_str) BookInfo.objects.filter(id=pk).update(**book_dict)
book_dict = model_to_dict(BookInfo.objects.get(id=pk))
return JsonResponse(book_dict) def delete(self, request, pk):
"""
删除
:param request:
:param pk:
:return:
"""
try:
book = BookInfo.objects.get(id=pk)
except Exception as e:
print(e)
return HttpResponse(status=404) book.delete()
return HttpResponse(status=204) """
urlpatterns = [
url(r'^books/$', views.BooksAPIView.as_view()),
url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
]
"""
通过(from rest_framework.views import APIView)中的APIView类构建一个RESTful风格的API接口的开发;
from .models import BookInfo from .serializers import BookInfoSerializer
from rest_framework.views import APIView
from rest_framework.response import Response class BooksAPIView(APIView):
"""
与django中的view相比
""" def get(self, request):
# 数据库中取数据;
books = BookInfo.objects.all()
# 序列化器的使用;
serializer = BookInfoSerializer(books, many=True)
# 返回数据
return Response(serializer.data) """
from app001 import views
urlpatterns = [
url(r'^books/$', views.BooksAPIView.as_view()),
]
""" """
此时继承的APIView与django中的view比较;
1,传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
2,视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
3,任何APIException异常都会被捕获到,并且处理成合适的响应信息;
4,在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
"""
通过APIView的子类GenericAPIView子类构建一个RESTful风格的API接口的开发;
from .models import BookInfo
from .serializers import BookInfoSerializer
from rest_framework.response import Response
from rest_framework.generics import GenericAPIView class BooksAPIView(GenericAPIView):
"""
与restframework中的APIView相比
"""
# 取出queryset对象
queryset = BookInfo.objects.all()
# 定义一个序列化器的类
serializer_class = BookInfoSerializer def get(self, request):
# 数据库中取数据;
qs = self.get_queryset()
# 序列化器的使用;
serializer = self.get_serializer(qs, many=True)
# 返回数据
return Response(serializer.data) class BookDetailView(GenericAPIView):
# 取出queryset对象
queryset = BookInfo.objects.all()
# 定义一个序列化器的类
serializer_class = BookInfoSerializer def get(self, request, pk):
# 数据库中取数据;
qs = self.get_object()
# 序列化器的使用;
serializer = self.get_serializer(qs)
# 返回数据
return Response(serializer.data) """
from app001 import views
urlpatterns = [
url(r'^books/$', views.BooksAPIView.as_view()),
url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
]
""" """
获取多个对象时候使用的方法( qs = self.get_queryset())
1,在这个视图中需要自己传入要返回的queryset对象;
2,要传来做序列化的类;
3,在定义的具体方法中来使用self.get_queryset()来获取类中的对象;
4,获取序列化的类然后处理数据;
5,将处理后的类返回到接口中; 获取单个对象使用的方法(qs = self.get_object())
步骤类似 总结:
在GenericAPIView的类中继承需要自己指定模型类;
自己指定方法的映射关系;
自己取对象;
自己取序列化的类;
自己返回数据
"""
(from rest_framework.generics import GenericAPIView)(from rest_framework import mixins)通过这两个子类构建一个RESTful风格的API接口的开发;
from .models import BookInfo
from .serializers import BookInfoSerializer
from rest_framework.generics import GenericAPIView
from rest_framework import mixins class BooksAPIView(mixins.ListModelMixin, GenericAPIView):
"""
与restframework中的APIView相比
"""
# 取出queryset对象
queryset = BookInfo.objects.all()
# 定义一个序列化器的类
serializer_class = BookInfoSerializer def get(self, request):
return self.list(request) class BookDetailView(mixins.RetrieveModelMixin, GenericAPIView):
# 取出queryset对象
queryset = BookInfo.objects.all()
# 定义一个序列化器的类
serializer_class = BookInfoSerializer def get(self, request, pk):
return self.retrieve(request) """
from app001 import views
urlpatterns = [
url(r'^books/$', views.BooksAPIView.as_view()),
url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
]
""" """
总结:
在mixins.RetrieveModelMixin与GenericAPIView相比较;
1,封装(self.get_queryset()的方法;
2,封装了self.paginate_queryset()的方法;
3,封装了serializer = self.get_serializer(queryset, many=True)的方法;
4,将序列化后的结果返回;
"""
(from rest_framework.generics import ListAPIView)类构建一个RESTful风格的API接口的开发;
from .models import BookInfo
from .serializers import BookInfoSerializer
from rest_framework.generics import ListAPIView class BooksAPIView(ListAPIView):
# 取出queryset对象
queryset = BookInfo.objects.all()
# 定义一个序列化器的类
serializer_class = BookInfoSerializer from rest_framework.generics import RetrieveAPIView class BookDetailView(RetrieveAPIView):
# 取出queryset对象
queryset = BookInfo.objects.all()
# 定义一个序列化器的类
serializer_class = BookInfoSerializer """
from app001 import views
urlpatterns = [
url(r'^books/$', views.BooksAPIView.as_view()),
url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
]
""" """
总结:
from rest_framework.generics import GenericAPIView
from rest_framework import mixins
等价与
from rest_framework.generics import ListAPIView 调用方式;
在get的方法中指明要调用的类中的封装的方法;
"""
(from rest_framework.viewsets import GenericViewSet)类构建一个RESTful风格的API接口的开发;
from .models import BookInfo
from .serializers import BookInfoSerializer
from rest_framework import mixins
from rest_framework.viewsets import GenericViewSet class BooksAPIViewSet(mixins.ListModelMixin,mixins.RetrieveModelMixin,GenericViewSet):
"""
mixins.ListModelMixin:实现了list的函数;
GenericViewSet(ViewSetMixin, generics.GenericAPIView):
ViewSetMixin 重写了as_view的方法(在url中将请求方式和action对应 queryset,serializer_class两个参数);
GenericAPIView(views.APIView) 实现了get_queryset()和get_object的方法:
"""
# 取出queryset对象
queryset = BookInfo.objects.all()
# 定义一个序列化器的类
serializer_class = BookInfoSerializer """
url的访问形式
urlpatterns = [
url(r'^books/$', views.BooksAPIViewSet.as_view({"get": "list"})),
url(r'^books/(?P<pk>\d+)/$', views.BooksAPIViewSet.as_view({"get": "retrieve"})),
]
""" """
总结:
from rest_framework.generics import GenericAPIView
from rest_framework import mixins
等价与
from rest_framework.generics import ListAPIView
"""
action自定义方法扩张类构建一个RESTful风格的API接口的开发;
from .models import BookInfo
from .serializers import BookInfoSerializer
from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action
from rest_framework.response import Response class BookInfoViewSet(ModelViewSet):
# 取出queryset对象
queryset = BookInfo.objects.all()
# 定义一个序列化器的类
serializer_class = BookInfoSerializer # detail为False 表示不需要处理具体的BookInfo对象
@action(methods=['get'], detail=False)
def latest(self, request):
"""
返回最新的图书信息
"""
book = BookInfo.objects.latest('id')
serializer = self.get_serializer(book)
return Response(serializer.data) # detail为True,表示要处理具体与pk主键对应的BookInfo对象
@action(methods=['put'], detail=True)
def read(self, request, pk):
"""
修改图书的阅读量数据
"""
book = self.get_object()
book.bread = request.data.get('read')
book.save()
serializer = self.get_serializer(book)
return Response(serializer.data) """
url的访问形式
urlpatterns = [
url(r'^books/$', views.BookInfoViewSet.as_view({'get': 'list'})),
url(r'^books/latest/$', views.BookInfoViewSet.as_view({'get': 'latest'})),
url(r'^books/(?P<pk>\d+)/$', views.BookInfoViewSet.as_view({'get': 'retrieve'})),
url(r'^books/(?P<pk>\d+)/read/$', views.BookInfoViewSet.as_view({'put': 'read'})),
]
""" """
总结:
1) ViewSet
继承自APIView,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。 在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。 2)GenericViewSet
继承自GenericAPIView,作用也与GenericAPIVIew类似,提供了get_object、get_queryset等方法便于列表视图与详情信息视图的开发。 3)ModelViewSet
继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。 4)ReadOnlyModelViewSet
继承自GenericAPIVIew,同时包括了ListModelMixin、RetrieveModelMixin。
"""
rest_framework中视图相关的更多相关文章
- iOS开发中视图相关的小笔记:push、modal、popover、replace、custom
在storyboard中,segue有几种不同的类型,在iphone和ipad的开发中,segue的类型是不同的. 在iphone中,segue有:push,modal,和custom三种不同的类型, ...
- Django框架rest_framework中APIView的as_view()源码解析、认证、权限、频率控制
在上篇我们对Django原生View源码进行了局部解析:https://www.cnblogs.com/dongxixi/p/11130976.html 在前后端分离项目中前面我们也提到了各种认证需要 ...
- Django缓存机制--rest_framework中节流源码使用的就是django提供的缓存api
一.配置缓存 https://www.jb51.net/article/124434.htm 二.缓存全站.页面.局部 三.自我控制的简单缓存API API 接口为:django.core.c ...
- Django的rest_framework的视图之基于通用类编写视图源码解析
我们上一篇博客讲解了如何使用mixins类实现rest_framework的视图,但是其中有很多的冗余的代码,我们这边在来优化一下 1.queryset的视图函数 首先看下对queryset操作的视图 ...
- 从零开始实现ASP.NET Core MVC的插件式开发(八) - Razor视图相关问题及解决方案
标题:从零开始实现ASP.NET Core MVC的插件式开发(八) - Razor视图相关问题及解决方案 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun ...
- Django框架03 /视图相关
Django框架03 /视图相关 目录 Django框架03 /视图相关 1. 请求相关 2.响应相关 3.FBV和CBV 视图(视图函数和视图类) 3.1 类视图 CBV 3.2 视图函数 FBV ...
- PyQt学习随笔:重写setData方法截获Model/View中视图数据项编辑的注意事项
根据<PyQt学习随笔:Model/View中视图数据项编辑变动实时获取变动数据的方法>可以重写从PyQt的Model类继承的setData方法来实时截获View中对数据的更改,但需要注意 ...
- PyQt学习随笔:Model/View中视图数据项编辑变动实时获取变动数据的方法
对于Model/View中视图的数据编辑后怎么能实时获取编辑的数据变动位置和变动情况查阅了一些资料,终于基本弄明白必须重写Model的setData方法才能截获.setData方法是视图中各种角色数据 ...
- 理解CSV文件以及ABAP中的相关操作
在很多ABAP开发中,我们使用CSV文件,有时候,关于CSV文件本身的一些问题使人迷惑.它仅仅是一种被逗号分割的文本文档吗? 让我们先来看看接下来可能要处理的几个相关组件的词汇的语义. Separat ...
随机推荐
- [转]CR, LF, CR/LF区别与关系
http://weizhifeng.net/talking-about-cr-lf.html 前言 在文本处理中,CR(Carriage Return),LF(Line Feed),CR/LF是不同操 ...
- CentOS7.5安装nodejs 转
CentOS7.5安装nodejs CentOS安装NodeJS 在CentOS下安装NodeJS有以下几种方法.使用的CentOS版本为7.2.CentOS其他版本的NodeJS安装大同小异,也可以 ...
- ELK使用3-Logstash
一.命令行输入输出操作 1.命令行输出: /application/elk/logstash/bin/logstash -e 'input { stdin{} } output { stdout{} ...
- LOJ#6433. 「PKUSC2018」最大前缀和 状压dp
原文链接https://www.cnblogs.com/zhouzhendong/p/LOJ6433.html 题解 枚举一个集合 S ,表示最大前缀和中包含的元素集为 S ,然后求出有多少个排列是这 ...
- day40 mycql 视图,触发器,存储过程,函数
视图,触发器,存储过程,自定义函数 -- 回顾 1.mysql 约束 1.非空 not null 2. 主键约束 primary key 3. 唯一约束 unique 4. 外键约束 foreign ...
- 【Java】idea找不到符号找不到类,但是却没有错误
编译错误,Ctrl+Shift+F9 将提示没有符号类的文件打开,右键单独编译一次,再重新打包即可解决: 特别说明:在Java的集成开发环境中,比如Eclipse.IDEA中,有常常有三种与编译相关的 ...
- scrapy response.xpath可以提取包含字符XX的标签
1. 筛选属性包含某字符串的标签(如id = 'bigbaong' 查询包含'big'字符的就可以筛选到) res = response.xpath("//a[contains(@id, ...
- tp5数据库链接
1在config/database.php中配置 1.1直接 return [ // 数据库类型 'type' => 'mysql', // 服务器地址 'hostname' => '12 ...
- Nowcoder contest 370B Rinne Loves Graph 【分层图最短路】
<题目链接> 题目大意: Island 是有一些奇怪的城镇和道路构成的(题目需要,游戏党勿喷),有些城镇之间用双向道路连接起来了,且每条道路有它自己的距离.但是有一些城镇已经被派兵戒严,虽 ...
- HDU-1247 Hat’s Words (暴力)【Trie树】
<题目链接> 题目大意: 给你一些单词,要求输出将该单词完全分成前.后两个单词之后,若这两个单词都在单词库中出现,则输出该单词. 解题分析: 将每个单词的每一位能够拆分的位置全部暴力枚举一 ...