hello!我是小J,每天一个小知识,一起学python,让技术无限发散。


DRF和Web

  • 1. web应用模式
    • 1.1 前后端不分离
    • 1.2 前后端分离
  • 2. 使用Django开发REST接口
    • 2.1 什么是REST
    • 2.2 REST的规范使用
      • 2.2.1 查询数据
      • 2.2.2 添加数据
      • 2.2.3 删除、修改数据
  • 3. DRF介绍和安装
    • 3.1 DRF介绍
    • 3.2 DRF特点介绍
    • 3.3 DRF使用
    • 3.4 序列化反序列化器
      • 3.4.1 序列化
      • 3.4.2 反序列化
    • 3.5 DRF视图
      • 3.5.1 两个基本类视图
      • 3.5.2 五个扩展类
        • 3.5.2.1 ListModelMixin列表视图扩展类
        • 3.5.2.2 CreateModelMixin创建视图扩展类
        • 3.5.2.3 RetrieveModelMixin详情视图扩展类
        • 3.5.2.4 UpdateModelMixin更新视图扩展类
        • 3.5.2.5 DestroyModelMixin删除视图扩展类
      • 3.5.3 扩展类视图的子类
        • 3.5.3.1 CreateAPIView
        • 3.5.3.2 ListAPIView
        • 3.5.3.3 ListCreateAPIView
        • 3.5.3.3 RetrieveAPIView
        • 3.5.3.4 UpdateAPIVIew
        • 3.5.3.5 DestoryAPIView
      • 3.5.4 视图集
  • 结束语

1. web应用模式

1.1 前后端不分离


  前后端不分离的应用模式中,前端代码和后端代码是在一块的,需要一个服务器就行,前端页面看到的效果是由后端控制,经后端渲染模板或重定向,后端控制着前端的展示,前后端的耦合度非常高。这种应用模式比较适合纯网页应用。但是当后端对接App时,App可能不需要后端返回一个html页面,而只需要接收数据本身,这样原本后端返回网页的接口不再适用于前端的App应用,为了实现对接App还需要再开发一套接口。

1.2 前后端分离


  在前后端分离的应用模式中,前端代码和后端代码时分开的,需要两个服务器,后端仅仅返回前端所需要的数据,不再渲染HTML页面,也不再控制前端的效果。至于前端用户能看到什么效果,均是由后端请求的数据加载到前端中,由前端觉得,网页有网页的处理方式,App有App的处理方式。但是无论哪种前端,所需要的数据基本相同,后端仅仅需要开发一套逻辑对外提供数据即可。在前后端分离的应用模式中,前端和后端的耦合度相对较低,通常后端开发的每个视图都称为一个接口(API),前端通过访问接口来对数据进行增删改查。

2. 使用Django开发REST接口

在了解什么是REST之前,我们需要了解一下API和Web更有助于我们了解REST,因为REST是基于Web为平台的一种架构风格,在开发API时需要遵循的一种风格,当然也存在其他规则可用。

2.1 什么是REST

  • API 英文为Application Programming Interface,中文为应用程序编程接口,是一些预先定义的函数,目的是为了提供应用程序与开发人员基于某些软件或硬件可以访问一组例程的能力,而无需理解内部工作机制的细节或无需访问源码。就像平时大家可以将其他软件里的内容分享到微信朋友圈,这些软件就和微信的API进行了交互。

  • Web是分布式信息系统为超文本文件和其他对象提供访问的入口,资源(对象)是Web架构的关键点,存在3个操作:

    所以REST,英文Resource Representational State Transfer的缩写,中文资源在网络中以某种表现形式进行状态转移就是选择通过http协议和uri,利用client/server model对资源进行增删改查操作。REST描述的是在网络中client和server的一种交互形式;REST本身不实用,实用的是如何设计 RESTful API(REST风格的网络接口)。对于资源的具体操作类型,由HTTP动词表示。常用的HTTP动词有下面五个(括号里是对应的SQL命令):

2.2 REST的规范使用

2.2.1 查询数据

在视图函数中编写类来查询数据库,查询数据是把数据构造为字典用来响应给浏览器(前端)

# 用类的方式来查询数据库
from .models import PeopleInfo,BookInfo
class BookInfoView(View):"""列表数据查询所有的图书数据"""def get(self,request):# books = BookInfo.objects.all()books = BookInfo.objects.filter(is_delete=False)print(books)book_list = []for book in books:book_dict = {'id':book.id,'name':book.name,'pub_date':book.pub_date,'readcount':book.readcount,'commentcount':book.commentcount,'image':book.image.url if book.image else ''}book_list.append(book_dict)print(book_list)return JsonResponse(book_list,safe=False)

路由:path('book/',views.BookInfoView.as_view()),

结果:

2.2.2 添加数据

使用post方法添加数据,获取数据,把数据进行转换为字典,构造响应的数据给浏览器(前端)

# 用类的方式来查询数据库
class BookInfoView(View):"""列表数据查询所有的图书数据"""def get(self,request):# books = BookInfo.objects.all()books = BookInfo.objects.filter(is_delete=False)print(books)book_list = []for book in books:book_dict = {'id':book.id,'name':book.name,'pub_date':book.pub_date,'readcount':book.readcount,'commentcount':book.commentcount,'image':book.image.url if book.image else ''}book_list.append(book_dict)print(book_list)return JsonResponse(book_list,safe=False)def post(self,request):"""添加数据:param request::return:"""# 获取到修改的数据# print(request)json_bytes = request.body# 转换为字符串json_str = json_bytes.decode()# 转换为字典import jsonbook_dict = json.loads(json_str)print(book_dict)# 保存数据book = BookInfo.objects.create(name = book_dict['name'],pub_date = book_dict['pub_date'])book_dict = {'id': book.id,'name': book.name,'pub_date': book.pub_date,'readcount': book.readcount,'commentcount': book.commentcount,'image': book.image.url if book.image else ''}return JsonResponse(book_dict)

结果:

2.2.3 删除、修改数据

修改数据流程:

  • ①获取要修改的数据,转换为字典
  • ②查询一下要修改的数据是否存在
  • ③存在数据就修改,并保存
  • ④响应

删除数据流程:获取删除的数据,去和数据库进行对比,如果有这个数据就删除,把删除的结果返回给浏览器

# 修改指定的数据
class BookDetailView(View):# 获取指定的数据def get(self,request,pk):# 查询这个ID对应的数据是否存在try:book = BookInfo.objects.get(id=pk)except Exception as e:return JsonResponse({'message':'error:%s'%e},status=404)book_dict = {'id': book.id,'name': book.name,'pub_date': book.pub_date,'readcount': book.readcount,'commentcount': book.commentcount,'image': book.image.url if book.image else ' '}return JsonResponse(book_dict)# 删除数据def delete(self,request,pk):try:book = BookInfo.objects.get(id=pk)except Exception as e:return JsonResponse({'message':'error:%s'%e},status=404)book.delete()return JsonResponse({'message':'delete success'},status=204)def put(self,request,pk):"""修改指定的某个图书数据"""try:book = BookInfo.objects.get(id=pk)except Exception as e:return JsonResponse({'message':'error:%s'%e},status=404)# 获取传过来的数据json_bytes = request.bodyprint(json_bytes)# 转换为字符串json_str = json_bytes.decode()# 转换为字典import jsonbook_dict = json.loads(json_str)print(book_dict)# 保存book.name = book_dict['name']book.pub_date = book_dict['pub_date']# 返回数据,构造数据json_dict = {'id':book.id,'name':book.name,'pub_date':book.pub_date,}return JsonResponse(data=json_dict,status=200)

路由:path('book/<int:pk>/',views.BookDetailView.as_view()),

结果:
使用put修改数据

使用delete删除数据

3. DRF介绍和安装

3.1 DRF介绍

  DRF框架全称:Django-REST-Framework,是一种后端框架,是基于RESTful风格的框架,该框架主要做的是前后的分离时接口的规范的编写。

3.2 DRF特点介绍

  • 提供了序列化器,自动进行序列化和反序列化
  • 提供了丰富的扩展类,简化了代码的编写
  • 可扩展性强
  • 丰富的定制层级
  • 内置了身份认证和权限控制以及限流

3.3 DRF使用

  • 安装
pip install djangorestframework
  • 注册应用
    在setting中的的INSTALLED_APP中添加rest_framework
# 注册子应用的地方
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','books.apps.BooksConfig',# 添加'rest_framework',
]

  • DRF的简单使用
    在books文件夹下新建一个serializer.py文件,在文件里创建一个简单的序列化模型类
from rest_framework import serializers
from books.models import BookInfo# 序列化模型类
class BookInfoSerializer(serializers.ModelSerializer):"""图书序列器"""class Meta:# 指定序列化的模型类model = BookInfo# 指定序列化器包含哪些字段fields = '__all__'  # __all__序列化模型类所有的字段

在views.py文件中新建一个视图类用于调用之前创建的序列化模型类

from rest_framework.viewsets import ModelViewSet
from .serializer import BookInfoSerializer
class BookInfoview(ModelViewSet):# ModelViewSet  自己实现了不同的请求方法# 查询模型类的数据   查询集queryset = BookInfo.objects.all()# 指定使用的序列化器的serializer_class = BookInfoSerializer

在urls.py文件中去创建路由

from rest_framework.routers import DefaultRouter
router = DefaultRouter()
# 向默认的路由器注册视图
router.register(r'books',views.BookInfoview)# 将这个路由器的信息追加到Django的路由列表中
urlpatterns += router.urls

结果:

点击页面中的地址:http://127.0.0.1:8000/books/

通过http://127.0.0.1:8000/books/1/

3.4 序列化反序列化器

  • 序列化:就是将数据从数据库(模型类)中查询出来,构造成字典数据,然后再返回的这个过程,结果是json。
  • 反序列化:将json的字符串类型转换为Django模型类对象的数据

3.4.1 序列化

  • 模型类序列化器

    • 依照模型类,自动生成序列化字段的序列化器,并且根据模型类生成验证函数和实现了create()和update()方法

      • 使用

        • 继承自serializer.Modelserializer
        • 通过class Meta指定元数据

          • models=参照的模型类名
          • fields=(需要为模型类中的那些字段生成),all表示所有字段
          • exclude=(不需要为模型类中的那些字段生成)
          • extra_kwargs={字段名:选项参数}可以为生成的序列化器字段增加约束
          • depth=嵌套返回的层级
          • read_only_fields=(指明只参加序列化返回的字段)
          • write_only_fields=(指明只参加反序列化验证的字段)

序列化流程

  • 1.准备序列化的模型类对象
  • 2.把模型类对象添加到指定的序列化器中
  • 3,获取数据转换后的数据

序列化器的作用:

  • 对数据进行转换

  • 进行数据的检验

  • 可用字段

  • 选项参数

  • 通用参数

  • 定义序列化模型类

from rest_framework import serializers
from books.models import BookInfoclass BookInfoSerializers(serializers.Serializer):# 接收到数据然后进行转换  IntegerField() 这个属性方法# read_only指定这个字段做序列化输出的id = serializers.IntegerField(label='ID',read_only=True)name = serializers.CharField(label='名称',max_length=50,read_only=True)pub_date = serializers.DateField(label='日期',required=False)readcount = serializers.IntegerField(label='阅读量',required=False)commentcount = serializers.IntegerField(label='评论量',required=False)is_delete = serializers.BooleanField(label='删除',required=False)image = serializers.ImageField(label='图片',required=False)

在终端中打开shell演示工具python manage.py shell

>>> from books.serializer import BookInfoSerializers
>>> from books.models import BookInfo
>>> book = BookInfo.objects.get(id=2)
>>> book
<BookInfo: 天龙八部>>>> ser = BookInfoSerializers(book)
>>> ser.data
{'id': 2, 'name': '天龙八部', 'pub_date': '1986-07-24', 'readcount': 36,
'commentcount': 40, 'is_delete': False, 'image': None}>>> books_qs = BookInfo.objects.all()
>>> ser = BookInfoSerializers(books_qs,many=True)
>>> ser.data
[OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pub_date', '1980-05-01
'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('imag
e', None)]), OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', '
1986-07-24'), ('readcount', 36), ('commentcount', 40), ('is_delete', Fals
e), ('image', None)]), OrderedDict([('id', 3), ('name', '笑傲江湖'), ('pu
b_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('is_del
ete', False), ('image', None)]), OrderedDict([('id', 4), ('name', '雪山飞
狐'), ('pub_date', '1987-11-11'), ('readcount', 58), ('commentcount', 24)
, ('is_delete', False), ('image', None)]), OrderedDict([('id', 10), ('nam
e', 'hello'), ('pub_date', '2022-05-11'), ('readcount', 0), ('commentcoun
t', 20), ('is_delete', True), ('image', None)]), OrderedDict([('id', 11),('name', 'python'), ('pub_date', '2022-05-10'), ('readcount', 20), ('com
mentcount', 0), ('is_delete', False), ('image', '/1.jpg')]), OrderedDict(
[('id', 27), ('name', 'python'), ('pub_date', '2022-05-14'), ('readcount'
, 0), ('commentcount', 0), ('is_delete', False), ('image', None)])]
>>>
  • 存在外键的模型类进行序列化输出
# 存在外键的模型类 怎么做序列化
class PeopleInfoSerializer(serializers.ModelSerializer):id = serializers.IntegerField(label='ID',read_only=True)name = serializers.CharField(label='名称',max_length=40)gender = serializers.IntegerField(label='性别',required=False)description = serializers.CharField(label='描述',required=False)is_delete = serializers.BooleanField(label='删除',required=False)book = serializers.StringRelatedField(label='图书')class Meta:model = PeopleInfofields = '__all__'

结果:

>>> from books.serializer import PeopleInfoSerializer
>>> from books.models import PeopleInfo
>>> people = PeopleInfo.objects.get(id=2)
>>> ser = PeopleInfoSerializer(people)
>>> ser.data
{'id': 2, 'name': '黄蓉', 'gender': 0, 'description': '打狗棍法', 'is_del
ete': False, 'book': '射雕英雄传'}
>>> peoples = PeopleInfo.objects.all()
>>> ser = PeopleInfoSerializer(peoples,many=True)
>>> ser.data
[OrderedDict([('id', 1), ('name', '郭靖'), ('gender', 1), ('description','降龙十八掌'), ('is_delete', False), ('book', '射雕英雄传')]), OrderedDi
ct([('id', 2), ('name', '黄蓉'), ('gender', 0), ('description', '打狗棍法
'), ('is_delete', False), ('book', '射雕英雄传')]), OrderedDict([('id', 3
), ('name', '黄药师'), ('gender', 1), ('description', '弹指神通'), ('is_d
elete', False), ('book', '射雕英雄传')]), OrderedDict([('id', 4), ('name'
, '欧阳锋'), ('gender', 1), ('description', '蛤蟆功'), ('is_delete', Fals
e), ('book', '射雕英雄传')]), OrderedDict([('id', 5), ('name', '梅超风'),('gender', 0), ('description', '九阴白骨爪'), ('is_delete', False), ('bo
ok', '射雕英雄传')]), OrderedDict([('id', 6), ('name', '乔峰'), ('gender'
, 1), ('description', '降龙十八掌'), ('is_delete', False), ('book', '天龙
八部')]), OrderedDict([('id', 7), ('name', '段誉'), ('gender', 1), ('desc
ription', '六脉神剑'), ('is_delete', False), ('book', '天龙八部')]), Orde
redDict([('id', 8), ('name', '虚竹'), ('gender', 1), ('description', '天
山六阳掌'), ('is_delete', False), ('book', '天龙八部')]), OrderedDict([('
id', 9), ('name', '王语嫣'), ('gender', 0), ('description', '神仙姐姐'),
('is_delete', False), ('book', '天龙八部')]), OrderedDict([('id', 10), ('
name', '令狐冲'), ('gender', 1), ('description', '独孤九剑'), ('is_delete
', False), ('book', '笑傲江湖')]), OrderedDict([('id', 11), ('name', '任
盈盈'), ('gender', 0), ('description', '弹琴'), ('is_delete', False), ('b
ook', '笑傲江湖')]), OrderedDict([('id', 12), ('name', '岳不群'), ('gende
r', 1), ('description', '华山剑法'), ('is_delete', False), ('book', '笑傲
江湖')]), OrderedDict([('id', 13), ('name', '东方不败'), ('gender', 0), (
'description', '葵花宝典'), ('is_delete', False), ('book', '笑傲江湖')]),OrderedDict([('id', 14), ('name', '胡斐'), ('gender', 1), ('description'
, '胡家刀法'), ('is_delete', False), ('book', '雪山飞狐')]), OrderedDict(
[('id', 15), ('name', '苗若兰'), ('gender', 0), ('description', '黄衣'),
('is_delete', False), ('book', '雪山飞狐')]), OrderedDict([('id', 16), ('
name', '程灵素'), ('gender', 0), ('description', '医术'), ('is_delete', F
alse), ('book', '雪山飞狐')]), OrderedDict([('id', 17), ('name', '袁紫衣'
), ('gender', 0), ('description', '六合拳'), ('is_delete', False), ('book
', '雪山飞狐')])]
>>>
  • 把关联的数据全部通过外键的方式查询出来进行序列化显示
    book = serializers.StringRelatedField(label='图书')更换为book = BookInfoSerializers()就可以实现
class PeopleInfoSerializer(serializers.ModelSerializer):id = serializers.IntegerField(label='ID',read_only=True)name = serializers.CharField(label='名称',max_length=40)gender = serializers.IntegerField(label='性别',required=False)description = serializers.CharField(label='描述',required=False)is_delete = serializers.BooleanField(label='删除',required=False)# book = serializers.StringRelatedField(label='图书')book = BookInfoSerializers()class Meta:model = PeopleInfofields = '__all__'

结果:

>>> from books.serializer import PeopleInfoSerializer,BookInfoSerializers
>>> from books.models import PeopleInfo
>>> people = PeopleInfo.objects.get(id=2)
>>> people
<PeopleInfo: 黄蓉>
>>> ser = PeopleInfoSerializer(people)
>>> ser.data
{'id': 2, 'name': '黄蓉', 'gender': 0, 'description': '打狗棍法', 'is_delete': False, 'book': OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pu
b_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)])}
>>> peoples = PeopleInfo.objects.all()
>>> ser = PeopleInfoSerializer(peoples,many=True)
>>> ser.data
[OrderedDict([('id', 1), ('name', '郭靖'), ('gender', 1), ('description', '降龙十八掌'), ('is_delete', False), ('book', OrderedDict([('id', 1), ('
name', '射雕英雄传'), ('pub_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)]))]), OrderedDict
([('id', 2), ('name', '黄蓉'), ('gender', 0), ('description', '打狗棍法'), ('is_delete', False), ('book', OrderedDict([('id', 1), ('name', '射雕英
雄传'), ('pub_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 3), (
'name', '黄药师'), ('gender', 1), ('description', '弹指神通'), ('is_delete', False), ('book', OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pu
b_date', '1980-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 4), ('name', '欧
阳锋'), ('gender', 1), ('description', '蛤蟆功'), ('is_delete', False), ('book', OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pub_date', '198
0-05-01'), ('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 5), ('name', '梅超风'), ('gend
er', 0), ('description', '九阴白骨爪'), ('is_delete', False), ('book', OrderedDict([('id', 1), ('name', '射雕英雄传'), ('pub_date', '1980-05-01'),('readcount', 12), ('commentcount', 34), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 6), ('name', '乔峰'), ('gender', 1), ('d
escription', '降龙十八掌'), ('is_delete', False), ('book', OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', '1986-07-24'), ('readcount',36), ('commentcount', 40), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 7), ('name', '段誉'), ('gender', 1), ('description', '
六脉神剑'), ('is_delete', False), ('book', OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', '1986-07-24'), ('readcount', 36), ('commentc
ount', 40), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 8), ('name', '虚竹'), ('gender', 1), ('description', '天山六阳掌'), ('
is_delete', False), ('book', OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', '1986-07-24'), ('readcount', 36), ('commentcount', 40), ('
is_delete', False), ('image', None)]))]), OrderedDict([('id', 9), ('name', '王语嫣'), ('gender', 0), ('description', '神仙姐姐'), ('is_delete', Fa
lse), ('book', OrderedDict([('id', 2), ('name', '天龙八部'), ('pub_date', '1986-07-24'), ('readcount', 36), ('commentcount', 40), ('is_delete', Fa
lse), ('image', None)]))]), OrderedDict([('id', 10), ('name', '令狐冲'), ('gender', 1), ('description', '独孤九剑'), ('is_delete', False), ('book'
, OrderedDict([('id', 3), ('name', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('is_delete', False), ('image
', None)]))]), OrderedDict([('id', 11), ('name', '任盈盈'), ('gender', 0), ('description', '弹琴'), ('is_delete', False), ('book', OrderedDict([('
id', 3), ('name', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('is_delete', False), ('image', None)]))]), Or
deredDict([('id', 12), ('name', '岳不群'), ('gender', 1), ('description', '华山剑法'), ('is_delete', False), ('book', OrderedDict([('id', 3), ('na
me', '笑傲江湖'), ('pub_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('is_delete', False), ('image', None)]))]), OrderedDict([('
id', 13), ('name', '东方不败'), ('gender', 0), ('description', '葵花宝典'), ('is_delete', False), ('book', OrderedDict([('id', 3), ('name', '笑傲
江湖'), ('pub_date', '1995-12-24'), ('readcount', 20), ('commentcount', 80), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 14),
('name', '胡斐'), ('gender', 1), ('description', '胡家刀法'), ('is_delete', False), ('book', OrderedDict([('id', 4), ('name', '雪山飞狐'), ('pub_d
ate', '1987-11-11'), ('readcount', 58), ('commentcount', 24), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 15), ('name', '苗若
兰'), ('gender', 0), ('description', '黄衣'), ('is_delete', False), ('book', OrderedDict([('id', 4), ('name', '雪山飞狐'), ('pub_date', '1987-11-1
1'), ('readcount', 58), ('commentcount', 24), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 16), ('name', '程灵素'), ('gender',
0), ('description', '医术'), ('is_delete', False), ('book', OrderedDict([('id', 4), ('name', '雪山飞狐'), ('pub_date', '1987-11-11'), ('readcount'
, 58), ('commentcount', 24), ('is_delete', False), ('image', None)]))]), OrderedDict([('id', 17), ('name', '袁紫衣'), ('gender', 0), ('description
', '六合拳'), ('is_delete', False), ('book', OrderedDict([('id', 4), ('name', '雪山飞狐'), ('pub_date', '1987-11-11'), ('readcount', 58), ('commen
tcount', 24), ('is_delete', False), ('image', None)]))])]
>>>

3.4.2 反序列化

反序列化流程

  • 1.准备要输入的数据 (json类型)
  • 2.把输入的数据添加到序列化器里面
  • 3.调用验证的方法去验证一下序列化器中转换的数据是否成功
  • 4.获取反序列化的数据 模型类对象数据
>>> from books.serializer import BookInfoSerializers
>>> book = {'name':'python'}
>>> ser.is_valid()
True
>>> ser.validated_data
OrderedDict([('name', 'python')])
>>>

3.5 DRF视图

3.5.1 两个基本类视图

  • ①APIView

    • 继承自Django的view类
    • 提供的额外功能
    • 身份认证
      • authentication_classes:身份认证类
  • 权限检查
    • permission_classes;权限检查类
  • 流量控制
    • throttle_classes:流量控制类
from rest_framework.views import APIView
from rest_framework import request, status
from rest_framework.response import Response
from .serializer import BookInfoSerializer
class BookListAPIView(APIView):"""列表视图  instance 做序列化输出的时候 data 做反序列化的时候"""def get(self,request):# 查询所有图书qs = BookInfo.objects.all()ser = BookInfoSerializer(instance=qs,many=True)return Response(ser.data)def post(self,request):# 获取传入的数据data = request.dataprint(data)ser = BookInfoSerializer(data=data)ser.is_valid(raise_exception=True)ser.save()return Response(ser.data,status=status.HTTP_201_CREATED)

结果:
get查看数据表

post添加数据

put修改数据

class BookDetailAPIView(APIView):def put(self,request,pk):try:book = BookInfo.objects.get(id=pk)except Exception as e:return Response(e,status=status.HTTP_404_NOT_FOUND)ser = BookInfoSerializer(instance=book,data=request.data)ser.is_valid(raise_exception=True)ser.save()return Response(ser.data,status=status.HTTP_201_CREATED)

结果:

删除数据:

class BookDetailAPIView(APIView):def put(self,request,pk):"""查询指定的pk 进行修改:param request: :param pk: :return: """try:book = BookInfo.objects.get(id=pk)except Exception as e:return Response(e,status=status.HTTP_404_NOT_FOUND)ser = BookInfoSerializer(instance=book,data=request.data)ser.is_valid(raise_exception=True)ser.save()return Response(ser.data,status=status.HTTP_201_CREATED)def delete(self,request,pk):"""查询指定的pk 进行删除:param request::param pk::return:"""try:book = BookInfo.objects.get(id=pk)except Exception as e:return JsonResponse(data={"magess":"没有这个数据"},status=status.HTTP_404_NOT_FOUND)# 如果有这个数据就删除book.delete()return JsonResponse(data={'magess':'delete success'},status=status.HTTP_204_NO_CONTENT)

结果:

  • ②GenericAPIView

    • 继承自APIView
    • 提供的额外功能
      • 四个属性

        • serialzer_class(指定使用的序列化器)
        • query_set(指定使用的查询集)
        • pagination_class(分页控制类)
        • filter_backends(指明过滤控制后端)
      • 四个方法

        • get_serializer(获取当前的序列化器):内部调用了get_serializer_class获取类属性指定的序列化器,然后实例化生成序列化器
        • get_object(获取更新的数据对象):内部调用了get_queryset获取指定的查询集
        • get_queryset(获取指定的查询集)
        • get_serializer_class(获取当前的序列化器类)
  • get查询数据

# GenericAPIView 继承自APIView 增加了对列表视图和详情视图可以使用的方法,进行了通用支持
from rest_framework.generics import GenericAPIView
"""
queryset = None  查询集  列表视图的查询集  接收查询集的数据
serializer_class = None  # 视图使用的序列化器
lookup_field = 'pk'  查询单个数据对象使用的条件默认是”pk“
lookup_url_kwarg = None   pk=books_id
filter_backends = api_settings.DEFAULT_FILTER_BACKENDS  过滤控制后端的数据显示
pagination_class = api_settings.DEFAULT_PAGINATION_CLASS  分页控制类
"""
class BookListGenericAPIView(GenericAPIView):# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef get(self,request):# 获取查询集qs = self.get_queryset()# 返回序列化器对象ser = self.get_serializer(qs,many=True)return Response(ser.data)

路由:path('books/',views.BookListGenericAPIView.as_view()),

结果:

  • post添加数据
 def post(self,request):# 获取传入的数据data = request.dataprint(data)ser = BookInfoSerializer(data=data)ser.is_valid(raise_exception=True)ser.save()return Response(ser.data,status=status.HTTP_201_CREATED)

结果:

  • put修改数据
    路由:path('books/<int:pk>/',views.BookDetailGenericAPIView.as_view()),
class BookDetailGenericAPIView(GenericAPIView):def put(self,request,pk):# 调用get_queryset()  去实现查询book = self.get_queryset()#ser = self.get_serializer(book,request.data)# 验证数据ser.is_valid(raise_exception=True)# 保存数据ser.save()return Response(ser.data)

结果:

  • delete删除数据
class BookDetailGenericAPIView(GenericAPIView):def put(self,request,pk):# 调用get_queryset()  去实现查询book = self.get_queryset()#ser = self.get_serializer(book,request.data)# 验证数据ser.is_valid(raise_exception=True)# 保存数据ser.save()return Response(ser.data)def delete(self,request,pk):"""查询指定的pk 进行删除:param request::param pk::return:"""try:# 查询指定的pkbook = BookInfo.objects.get(id=pk)except Exception as e:return Response(status=status.HTTP_404_NOT_FOUND,data={"magess":"数据不存在"})# 如果有这个数据就删除book.delete()return Response(status=status.HTTP_204_NO_CONTENT)

结果:

3.5.2 五个扩展类

3.5.2.1 ListModelMixin列表视图扩展类

路由:path('books/',views.BookListModelMixin.as_view())

# ListModelMixin 列表视图扩展类
from rest_framework.mixins import ListModelMixinclass BookListModelMixin(ListModelMixin,GenericAPIView):# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef get(self,request):return self.list(request)

结果:

3.5.2.2 CreateModelMixin创建视图扩展类

  • 路由:path('books/',views.BookCreateModelMixin.as_view()),
# CreateModelMixin 创建视图扩展类 添加视图扩展类
from rest_framework.mixins import CreateModelMixinclass BookListModelMixin(CreateModelMixin,ListModelMixin,GenericAPIView):# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器serializer_class = BookInfoSerializerdef get(self,request):return self.list(request)def post(self,request):return self.create(request)

post添加数据结果:

get获取数据结果:

3.5.2.3 RetrieveModelMixin详情视图扩展类

路由:path('books/',views.BookRetrieveModelMixin.as_view()),

# RetrieveModelMixin 详情视图扩展类 用于单个数据的查询 这个必须在路由里面传入参数
from rest_framework.mixins import RetrieveModelMixinclass BookRetrieveModelMixin(RetrieveModelMixin,CreateModelMixin,ListModelMixin,GenericAPIView):# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef get(self,request,pk):return self.list(request)

结果:

3.5.2.4 UpdateModelMixin更新视图扩展类

路由:path('books/<init:pk>/',views.BookUpdateModelMixin.as_view()),

# UpdateModelMixin 更新视图扩展类
from rest_framework.mixins import UpdateModelMixinclass BookUpdateModelMixin(UpdateModelMixin,RetrieveModelMixin,CreateModelMixin,ListModelMixin,GenericAPIView):"""更新视图"""# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef get(self,request,pk):return self.retrieve(request,pk)def put(self,request,pk):return self.update(request,pk)

get获取数据结果:

put修改数据结果:

3.5.2.5 DestroyModelMixin删除视图扩展类

路由:path('books/<int:pk>/', views.BookDestroyModelMixin.as_view()),

# DestroyModelMixin 删除视图扩展类
from rest_framework.mixins import DestroyModelMixinclass BookDestroyModelMixin(DestroyModelMixin,UpdateModelMixin,RetrieveModelMixin,CreateModelMixin,ListModelMixin,GenericAPIView):# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef get(self, request, pk):return self.retrieve(request, pk)def put(self, request, pk):return self.update(request, pk)def delete(self, request, pk):return self.destroy(request, pk)

结果:

3.5.3 扩展类视图的子类

继承扩展类中的一i邪恶方法和基类中的一些方法,也不能单独继承使用必须继承一个基类。

3.5.3.1 CreateAPIView

保存单个数据,实现了post方法,路由:path('books/',views.BookgenericsCreateAPIView.as_view()),

from rest_framework.generics import CreateAPIView
class BookgenericsCreateAPIView(CreateAPIView):# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef post(self, request, *args, **kwargs):return self.create(request)

结果:

3.5.3.2 ListAPIView

返回多个数据,实现了get方法:path('books/',views.BookgenericsListAPIView.as_view()),

from rest_framework.generics import ListAPIView
class BookgenericsListAPIView(ListAPIView):"""Concrete view for listing a queryset."""# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef get(self, request, *args, **kwargs):return self.list(request)

结果:

3.5.3.3 ListCreateAPIView

路由:path('books/<int:pk>/',views.BookgenericsListCreateAPIView.as_view()),

from rest_framework.generics import ListCreateAPIView
class BookgenericsListCreateAPIView(ListCreateAPIView):"""Concrete view for listing a queryset or creating a model instance."""# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef get(self, request, pk):return self.list(request, pk)def post(self, request,pk):return self.create(request,pk)

结果:
post添加数据:

get获取数据:

3.5.3.3 RetrieveAPIView

返回单个数据,实现了get方法,路由:path('books/',views.BookgenericsRetrieveAPIView.as_view()),

from rest_framework.generics import RetrieveAPIViewclass BookgenericsRetrieveAPIView(RetrieveAPIView):"""Concrete view for retrieving a model instance."""# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef get(self, request, *args, **kwargs):return self.retrieve(request)

结果:

3.5.3.4 UpdateAPIVIew

更新数据,实现了put方法和patch方法,路由:path('books/<int:pk>/',views.BookgenericsUpdateAPIView.as_view()),

from rest_framework.generics import UpdateAPIView
class BookgenericsUpdateAPIView(UpdateAPIView):"""Concrete view for updating a model instance."""# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef put(self, request, *args, **kwargs):return self.update(request)def patch(self, request, *args, **kwargs):return self.partial_update(request)

结果:
put修改数据:

patch修改数据:

3.5.3.5 DestoryAPIView

删除数据,实现了delete方法,路由: path('books/<int:pk>/',views.BookgenericsDestroyAPIView.as_view()),

from rest_framework.generics import DestroyAPIView
class BookgenericsDestroyAPIView(DestroyAPIView):"""Concrete view for deleting a model instance."""# 指定查询集queryset = BookInfo.objects.all()# 指定序列化器类serializer_class = BookInfoSerializerdef delete(self, request, *args, **kwargs):return self.destroy(request)

结果:

3.5.4 视图集

  • 视图集不需要按照请求方式来定义方法名,但是需要在as_view中实现请求方式和方法名的映射关系
  • 常用的视图集
    • ViewSet

      • 继承自APIView和ViewSetMixin
      • ViewSetMixin主要实现了as_view中请求方式和方法名的映射处理
    • GenericViewSet

      • 继承自GenericAPIView和其他的扩展类

结束语

  本文属于作者原创,转载请注明出处,不足之处,希望大家能过给予宝贵的意见,如有侵权,请私信。每天一个小知识,一起学python,让技术无限发散

python开发框架——Django基础知识(十一)相关推荐

  1. python开发框架——Django基础知识(九)

      hello!我是小J,每天一个小知识,一起学python,让技术无限发散. 模型类--增删改查 1. 演示工具shell的使用 2. 添加数据 3. 查询数据 3.1 基础条件查询 3.2 过滤查 ...

  2. python开发框架——Django基础知识(七)

      hello!我是小J,每天一个小知识,一起学python,让技术无限发散. 模板 1. 模板配置 1.1 模板简介 1.2 模板的使用流程 1.3 模板配置 2. 模板使用 2.1 变量 2.2 ...

  3. Python培训入门基础知识学什么?

    Python培训基础知识主要是针对一些零基础的同学安排的,虽说Python是相对比较简单的一门编程语言,但是没有基础的同学还是要进行系统的学习,那么Python培训入门基础知识学什么呢?来看看下面小编 ...

  4. 零基础可以学python吗-学Python需要什么基础知识?零基础可以学Python吗?

    学Python需要什么基础知识?一般来说,想要学Python最好具备一定的计算机专业知识,尤其是数学和英语不错的话,对学Python也有一定的帮助.但是零基础的学习者就不能学Python了吗?当然不是 ...

  5. 学python需要什么基础知识-学Python需要什么基础知识?零基础可以学Python吗?

    学Python需要什么基础知识?一般来说,想要学Python最好具备一定的计算机专业知识,尤其是数学和英语不错的话,对学Python也有一定的帮助.但是零基础的学习者就不能学Python了吗?当然不是 ...

  6. 学python需要什么基础知识-没学过Python先要学习哪些基础知识?

    零基础学Python应该学习哪些入门知识 关于零基础怎么样能快速学好Python的问题,百度提问和解答的都很多,你可以百度下看看.我觉得从个人自学的角度出发,应从以下几个方面来理解: 1 为什么选择学 ...

  7. python基础知识资料-学习Python列表的基础知识汇总

    千里之行,始于足下.要练成一双洞悉一切的眼睛,还是得先把基本功扎扎实实地学好.今天,本喵带大家仔细温习一下Python的列表.温故而知新,不亦说乎. 当然,温习的同时也要发散思考,因为有些看似无关紧要 ...

  8. python内置函数用来打开或创建文件_2020年《python程序设计》基础知识及程序设计598题XS[含参考答案]...

    2020年<python程序设计>基础知识及程序设计 598题[含参考答案] 一.填空题 1.表达式 len('中国'.encode('utf-8')) 的值为___________.(6 ...

  9. python适合零基础的人吗_学Python需要什么基础知识?零基础可以学Python吗?

    学Python需要什么基础知识?一般来说,想要学Python最好具备一定的计算机专业知识,尤其是数学和英语不错的话,对学Python也有一定的帮助.但是零基础的学习者就不能学Python了吗?当然不是 ...

最新文章

  1. FPGA之道(45)正确的变量访问思路
  2. 快速写出较好CSS的5种方法
  3. 计算机用户域怎么删除,如何查找并删除AD域中多余的计算机帐号?
  4. matlab车辆贪心作业调度,贪心算法-区间调度-Interval Scheduling
  5. 【Redis】使用Redis Sentinel实现Redis HA
  6. [css] 写出你遇到过IE6/7/8/9的BUG及解决方法
  7. vue 导入excel插件_Vue框架下实现导入导出Excel、导出PDF
  8. cmd完成拷贝文件,并生成两个快捷脚本
  9. 从像素坐标到相机坐标_多视图几何基础——深入理解相机内外参数
  10. 在C语言中如何高效地复制和连接字符串?
  11. Sonar - 部署常见问题及解决方法
  12. Java开发、网络爬虫、自然语言处理、数据挖掘简介
  13. 用python设计数独的心得体会_Python生成数独矩阵
  14. 向日葵RCE后续利用之本地提权
  15. 【Pyecharts50例】GEO图中忽略不存在的位置
  16. Markdown插入图片
  17. 远程执行模块和黏包 socketserve hamc模块验证合法性
  18. 《IDOLM@STER2》快速通关心得
  19. Linux安装系统注意事项及系统初始化
  20. SAP教程之 Sap S/4HANA的未来是什么?它会取代 SAP ABAP 吗?

热门文章

  1. 在everedit编辑器中安装python环境
  2. SIGPIPE的设计意图
  3. qeePHP Qform表单验证方法介绍
  4. UVA-1595 Symmetry
  5. 1062lcd在dxp哪个库_dxp_2004_元件库中的常用元件所在位置
  6. 用MRTG监测Linux系统网络、CPU、内存和硬盘情况
  7. solrj mysql_solr7.4.0+mysql+solrj(简而优美)
  8. php解析rss格式新闻源,订阅一些RSS新闻源来阅读电子报纸
  9. 常用开发语言及相应框架
  10. PySNMP实现自定义trap(SNMPv3)