??hello!我是小J,每天一个小知识,一起学python,让技术无限发散。
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.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.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:
"""
json_bytes = request.body
json_str = json_bytes.decode()
import json
book_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):
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.body
print(json_bytes)
json_str = json_bytes.decode()
import json
book_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__'
在views.py文件中新建一个视图类用于调用之前创建的序列化模型类
from rest_framework.viewsets import ModelViewSet
from .serializer import BookInfoSerializer
class BookInfoview(ModelViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
在urls.py文件中去创建路由
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'books',views.BookInfoview)
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 BookInfo
class BookInfoSerializers(serializers.Serializer):
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 = PeopleInfo
fields = '__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 = BookInfoSerializers()
class Meta:
model = PeopleInfo
fields = '__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:身份认证类
- 权限检查
- 流量控制
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.data
print(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查询数据
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 = BookInfoSerializer
def get(self,request):
qs = self.get_queryset()
ser = self.get_serializer(qs,many=True)
return Response(ser.data)
路由:path('books/',views.BookListGenericAPIView.as_view()),
结果:
def post(self,request):
data = request.data
print(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):
book = self.get_queryset()
ser = self.get_serializer(book,request.data)
ser.is_valid(raise_exception=True)
ser.save()
return Response(ser.data)
结果:
class BookDetailGenericAPIView(GenericAPIView):
def put(self,request,pk):
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:
book = 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())
from rest_framework.mixins import ListModelMixin
class BookListModelMixin(ListModelMixin,GenericAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
def get(self,request):
return self.list(request)
结果:
3.5.2.2 CreateModelMixin创建视图扩展类
- 路由:
path('books/',views.BookCreateModelMixin.as_view()),
from rest_framework.mixins import CreateModelMixin
class BookListModelMixin(CreateModelMixin,ListModelMixin,GenericAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
def 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()),
from rest_framework.mixins import RetrieveModelMixin
class BookRetrieveModelMixin(RetrieveModelMixin,CreateModelMixin,ListModelMixin,GenericAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
def get(self,request,pk):
return self.list(request)
结果:
3.5.2.4 UpdateModelMixin更新视图扩展类
路由:path('books/<init:pk>/',views.BookUpdateModelMixin.as_view()),
from rest_framework.mixins import UpdateModelMixin
class BookUpdateModelMixin(UpdateModelMixin,RetrieveModelMixin,CreateModelMixin,ListModelMixin,GenericAPIView):
"""
更新视图
"""
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
def 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()),
from rest_framework.mixins import DestroyModelMixin
class BookDestroyModelMixin(DestroyModelMixin,UpdateModelMixin,RetrieveModelMixin,CreateModelMixin,ListModelMixin,GenericAPIView):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
def 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 = BookInfoSerializer
def 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 = BookInfoSerializer
def 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 = BookInfoSerializer
def 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 RetrieveAPIView
class BookgenericsRetrieveAPIView(RetrieveAPIView):
"""
Concrete view for retrieving a model instance.
"""
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
def 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 = BookInfoSerializer
def 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 = BookInfoSerializer
def delete(self, request, *args, **kwargs):
return self.destroy(request)
结果:
3.5.4 视图集
- 视图集不需要按照请求方式来定义方法名,但是需要在as_view中实现请求方式和方法名的映射关系
- 常用的视图集
-
ViewSet
- 继承自APIView和ViewSetMixin
- ViewSetMixin主要实现了as_view中请求方式和方法名的映射处理
-
GenericViewSet
结束语
??本文属于作者原创,转载请注明出处,不足之处,希望大家能过给予宝贵的意见,如有侵权,请私信。每天一个小知识,一起学python,让技术无限发散
|