DRF全局总结
基础部分
一、创建工程
1、创建虚拟环境
python -m venv 路径
2、安装Django
进入虚拟环境 pip install Django
3、创建项目
django-admin startproject 项目名.
注意:这里是已经创建的虚拟环境,再在下面创建项目,这时使用虚拟环境的名称后面加个’.'这样创建出来的项目不会出现多个层级
4、创建子应用
python manage.py startapp 子应用名 # python manage.py startapp projects
5、注册子应用
在setting - > INSTALLED_APPS中添加
6、设置路由
7、创建视图
二、接收数据处理
1、请求体数据
当在body中传送的json数据,是以byte传送的。(要写解码,在把文本转成字典)
2、pk接受
3、数据返回JsonResponse
三、ORM框架
1、关联数据库
a、创建数据库和用户
b、配置数据库
settings.py文件中配置对应的IP、用户名、密码、数据库
c、安装mysqlclient
d、安装 pymysql
项目__init__.py文件中加入下面内容
import pymysql
pymysql.install_as_MySQLdb()
e、安装 cryptography
2、数据库的增删改查
from django.db.models import Q
from django.http import JsonResponse
from django.shortcuts import render, HttpResponse
from django.views import View
from app01.models import Projects def projects(request):
# 创建数据
# 方法一
# one_obj = Projects(name='小假123', leader='小块2', tester='小时2',
# programer='大赛2', publish_app='时间控制器2', desc='这是一个时间的项目2')
# print(one_obj)
# one_obj.save()
# 方法二
# Projects.objects.create(name='小假1234', leader='小块24', tester='小时24',
# programer='大赛24', publish_app='时间控制器24', desc='这是一个时间的项目24') # 增加外键的值 外键=关联模型对象(一对象)
# 外键_id = 关联的模型对象.id
# 添加interface的interface_id(interface(多)project(一))
# interface = project
# interface_id = project_id # 查
# 1、获取一个数据的所有记录
# QuerySet查询集, 就相当于一个列表(存放所有项目对象的列表)
# queryset查询集,简单理解为被那条件筛选后满足条件的一个表,要想得到想要的结果,可以继续筛选
# qs = Projects.objects.all()
# for i in qs:
# print(f'{type(i)}')
# print(i) # 2、获取摸一个指定的记录,get()
# get方法只能返回一条记录
# 如果返回多条记录或查询记录不存在那么会抛出异常
# get方法的参数往往为主键或者唯一键
# data_project = Projects.objects.get(id=1)
# data = data_project.leader # 3、获取某一些记录,filter()或者exlude()
# 使用filter返回的是满足条件之后的queryset,exlude是不满足条件的queryset
# data_project = Projects.objects.filter(leader__contains=2)
# qs_project = Projects.objects.exclude(leader__icontains=2)
# print(type(qs_project))
# data = qs_project.get(id=5) # 4、关联查询
# 外键字段__从表字段名__
# qs_project = Projects.objects.filter(interface__name='Login')
# data = qs_project[0] # 5、比较查询
# __gt >
# __gte >=
# __lt <
# __lte <=
# qs_data = Projects.objects.filter(id__gt=5)
# data = qs_data.get(id=9) # 6、逻辑关系,多个条件查询
# 如果给filter指定多个条件,那么条件之间与的关系
# qs_data = Projects.objects.filter(id__gt=5,leader__contains=2)
# data = qs_data.get(id=7)
# # Q或条件 F
# qs_data = Projects.objects.filter(Q(id__gt=5) | Q(leader__contains=2))
# data = qs_data.get(id=7) # 7、查询集的操作
# 查询集相当于一个列表,支持列表中的的大多数操作
# 查询集是对数据库操作的一种优化
# 查询集会缓存结果
# 惰性查询
# 查询集,简单理解为被那条件筛选后满足条件的一个表,要想得到想要的结果,可以继续筛选 # 8、排序
# 默认为从小到大排序
# 在字段前面添加-号,代表从大到小排序
# qs_data = Projects.objects.filter(id__gt=5).order_by('-name')
# data = qs_data.first()
# return HttpResponse(data) # 更新操作
# 1、现获取到要修改的模型对象
# 2、修改
# 3、保存
# one_data = Projects.objects.get(id=9)
# one_data.name = '这是一个更新操作'
# one_data.save() # Projects.objects.get(id=9).update(name='更新操作') # 删除操作
# 1、先获取要删除的模型对象
# 2、删除
# one_data = Projects.objects.get(id=2)
# one_data.delete()
# Projects.objects.get(id__in=[2,7]).delete()
# return HttpResponse("OK")
数据库增删改查
# 获取数据
# 方法一获取所有数据,返回一个QuerySet查询集
# h = Projects.objects.all()
# print(h[:1])
# for i in h:
# print(i.name) # 1获取特定某个指定的记录
'''
1.get返回的是一个模型类对象
2.get只能查询一条数据,查询结果出现多条或者不存在就会报错
3,get主要用于主键和唯一值的查询
'''
# one_Projecr = Projects.objects.get(id=3) # 2读取部分数据 filter,exclude
"""
filter : 返回满足条件的查询集合
exclude : 返回不满足条件的查询集合
"""
# #读取id为1的数据
# qs = Projects.objects.filter(id=1)
# #读取ID不为1的数据
# qs1 = Projects.objects.exclude(id=1) # 3模糊查询 # mh = Projects.objects.filter(leader__contains='icon') #包含icon
# mh1 = Projects.objects.filter(leader__icontains='con') #忽略查询结果的大小写icon
# mh2 = Projects.objects.filter(leader__startswith='i') #以i开头的
# mh3 = Projects.objects.filter(leader__istartswith='') # 忽略大小
# mh4 = Projects.objects.filter(leader__endswith='n') #以n结尾的
# mh5 = Projects.objects.filter(leader__iendswith='n')
# mh6 = Projects.objects.filter(leader__regex='') #正则匹配
# mh7= Projects.objects.filter(leader__iregex='')
# mh8 = Projects.objects.filter(leader__exact='icon') #精确匹配
# mh9 = Projects.objects.filter(leader__iexact='icon')
# mh10 = Projects.objects.filter(leader__in=['icon','宋茜'])#包含 # 4关联查询
'''
格式 外键字段__从表字段名__
如果是多个表 A表__C表__从表字段名_
'''
# qs = Projects.objects.filter(project2s__name__contains='创建项目') # 5比较查询
"""
__gt 大于
__gte 大于等于
__lt 小于
__lte 小于等于
返回查询集
"""
# qs = Projects.objects.filter(id__gt=3) #6逻辑查询
'''
可以组合& 和| 操作符以及使用括号进行分组来编写任意复杂的Q 对象
允许组合正常的查询和取反(NOT) 查询 '~'
''' # qs1 =Projects.objects.filter(name='接口自动',leader='宋茜') #且的关系
# from django.db.models import Q
# qs1 = Projects.objects.filter(Q(leader='icon')|Q(leader='宋茜')) #或的关系
# qs2 = Projects.objects.filter(Q(leader='icon')&~Q(tester='魏书')) #and的 #7.查询集的操作
"""
7.1 查询集相当与一个列表,支持列表的大多数就操作(数字索引,正向切片,for循环)
7.2 查询集是对数据库的一种操作
7.3 查询及会缓存结果
7.4 惰性查询
7.5 查询集支持链式操作
first() 第一个
"""
#获取链式查询的第一个结果
qs = Projects.objects.filter(leader__contains='icon').filter(tester__contains='小明1').first()
qs = Projects.objects.filter(leader__contains='icon').filter(tester__contains='小明1').last()
补充数据查询
#F查询两个字段的值做比较
"""
Django 提供 F() 来做这样的比较。F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值。
Django 支持 F() 对象之间以及 F() 对象和常数之间的加减乘除和取模的操作。
"""
from django.db.models import F
qs = Projects.objects.filter(leader=F('tester'))
F查询两个字段的值做比较
#分组查询
# qs = Project2s.objects.all().annotate(h = Count('project_id'))
qs = Project2s.objects.values('project_id').annotate(Count('project_id'))
#聚合查询
'''
aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的标识符
,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。
为聚合值指定一个名称 名称 = 集合值标识符() '''
# from django.db.models import Max,Avg,F,Q,Min,Sum
# qs = Projects.objects.all().aggregate(idmax = Max('id'),idmin=Min('id'),idavg = Avg('id'),
# idsum =Sum('id'))
小结:
增
方法一:Projects(字段=“值”…)
方法二:Projects.objects.create(字段=“值”…)
查
一、all
- QuerySet查询集, 就相当于一个列表(存放所有项目对象的列表)
- queryset查询集,简单理解为被那条件筛选后满足条件的一个表,要想得到想要的结果,可以继续筛选
二、get
- get方法只能返回一条记录
- 如果返回多条记录或查询记录不存在那么会抛出异常
- get方法的参数往往为主键或者唯一键
三、filter()或者exlude()
- 使用filter返回的是满足条件之后的queryset,exlude是不满足条件的queryset
四、关联外键查询
- 外键字段__从表字段名
# 多查一 (objects.filter(多模型名小写_多的模型属性=值))
BookInfo.objects.filter(heroinfo_hname='大侠') # 一查多 (多.objects.filter(外键__一的属性=值))
HeroInfo.objects.filter(bookinfo__id__gt=1) # 多查一(先把多查出来,然后再利用多里面的外键 查到一)
hero = HeroInfo.objects.get(hname='大侠')
book = hero.hbook # 如果有外键直接当前模型对象.外键 代表获取外键模型对象 # 一查多(先把一查出来,然后用一.多的那个模型名小写_set 查到多)
book = BookInfo.objects.get(id=1)
book.heroinfo_set.all() # 如果当前没有外键的一方 应该是当前模型对象.多的一方模型小写_set
五、比较查询
- __gt >
- __gte >=
- __lt <
- __lte <=
六、逻辑关系,多个条件查询
- 如果给filter指定多个条件,那么条件之间与的关系
- Q或条件 F (Q(id__gt=5) | Q(leader__contains=2))
七、查询集的操作
- 查询集相当于一个列表,支持列表中的的大多数操作
- 查询集是对数据库操作的一种优化
- 查询集会缓存结果
- 惰性查询
- 查询集,简单理解为被那条件筛选后满足条件的一个表,要想得到想要的结果,可以继续筛选
八、排序 order_by(’-name’)
- 默认为从小到大排序
- 在字段前面添加-号,代表从大到小排序
九、聚合查询(aggregate)(点击看详情)
使用aggregate,聚合对应的字段
res=models.Book.objects.aggregate(c=Count("id"),max=Max("price"),min=Min("price"))
print(res,type(res)
十、分组查询(annotate)(点击看详情)
annotate是先分组,后续使用values控制展示的字段
统计每一本以"菜"开头的书籍的作者个数: res = models.Book.objects.filter(title__startswith="菜").annotate(c = Count("authors__name")).values("title","c")
print(res)
更新
- 现获取到要修改的模型对象
- 修改
- 保存
one_data = Projects.objects.get(id=9)
one_data.name = '这是一个更新操作'
one_data.save()
删除
- 先获取要删除的模型对象
- 删除
one_data = Projects.objects.get(id=2)
one_data.delete()
序列化和反序列化
序列化:将模型对象转换为字典或者json的过程,叫做序列化的过程。
反序列化:将客户端传递的数据保存转化到模型对象的过程,叫做反序列化的过程。 核心:
1. 将数据库数据序列化为前端所需要的格式,并返回;
2. 将前端发送的数据反序列化为模型类对象,并保存到数据库中。
一、Django RestFrame Work 简介/安装
安装
安装: pip install djangorestframework
在settings.py的INSTALLED_APPS中添加’rest_framework’
INSTALLED_APPS = [
...
'rest_framework', # 添加
]
二、序列化器Serializer
Serializer序列化类定义
1、在子app下新建Serializers.py
2、定义序列化器
# 定义模型类
class 模型类(modles.Model):
模型字段 = models.字段类型(选项参数)
# 定义序列化器类
from rest_framework import serializers
class 序列化器类(serializers.Serializer):
序列化器字段= serializers.字段类型(选项参数
序列化器类(instance=None,data={},**kwargs)
1.进行序列化操作,将对象传递给instance
2.进行反序列化操作,将数据传递给data
模型类常用字段类型
AutoField: 自增长字段,通常不用,如果未在Model中显示指定主键,django会默认建立一个整型的自增长主键字段
BooleanField: 布尔型,值为True或False,在管理工具表现为checkbox
CharField: 单行字符串字段,CharField有一个必填参数:
CharField.max_length:字符的最大长度,django会根据这个参数在数据库层和校验层限制该字段所允许的最大字符数。
TextField: textarea字段,即多行文本字段
DateField: 日期字段
auto_now:当对象被保存时,自动将该字段的值设置为当前时间.通常用于表示 “last-modiied” 时间戳;
auto_now_add:当对象首次被创建时,自动将该字段的值设置为当前时间.通常用于表示对象创建时间。
IntegerField: 整型字段
Field的可选项:
choices:一个用来选择值的2维元组。第一个值是实际存储的值,第二个用来方便进行选择。
如SEX_CHOICES= ((‘F’,'Female’),(‘M’,'Male’),)
default: 设定缺省值
primary_key: 设置主键,如果没有设置django创建表时会自动加上:
unique: 数据唯一
unique_for_date: 日期唯一
verbose_name: 字段描述
help_text: 字段描述
null: 字段是否可以为空
外键 ForeignKey
# Student表和Teacher表一对多关系
# 在Students表新建下面外键
teacher=models.ForeignKey(Teacher,on_delete=models.CASCADE,related_name='student_teacher',default='')
# 第一个参数为关联的模型路径(应用名.模型类)或者模型类
# 第二个参数设置得是,当父表删除后,该字段的处理方式
# CASCADE 子表也会删除,
# SET_NULL 当前外键值会被设置为None
# PROJECT 会报错
# SET_DEFAULT 设置默认值,同时需要指定默认值,null=True
on_delete=models.CASCADE # 作用主表删除后字表也对应删除信息
related_name='student_teacher' # 使用teacher查询数据时,使用的关联关系 # 一查询多方式一
teacher = teacher.object.get(id=1)
teacher.student_set.all() # 一查询多方式二
teacher = teacher.object.get(id=1)
teacher.student_teacher.all()
序列化器字段类型
在定义序列化器类的字段时,write_only和read_only默认值为False,说明这个字段既在序列化时使用,也在反序列化时使用。
通用选项参数:
write_only: 设置为True,该字段只在序列化时使用,反序列化操作时不使用
read_only: 设置为True,该字段只在序列化时使用,反序列化时不使用
default: 设置序列化和反序列化时所使用的默认值
requird: 默认值是True,指明在进行反序化时此字段是否必须传入
allow_null 表明该字段是否允许传入None,默认False
validators 该字段使用的验证器
error_messages 包含错误编号与错误信息的字典
label 用于HTML展示API页面时,显示的字段名称
help_text 用于HTML展示API页面时,显示的字段帮助提示信息
字段校验方式
# 单字段校验器
# 自定义校验器顺序
# 字段定义时的限制,包含了validators列表条目从左到右进行校验 -》但字段校验validate_字段名
# 单字段校验validate_字段名
# 校验之后一定要返回对应的值
def validate_name(self, value):
if not value.endswith('项目'):
raise serializers.ValidationError('项目名以"项目"结尾')
# 校验之后一定要返回对应的值
return value # 多字段联合校验
def validate(self, attrs):
if '小明' not in attrs['leader'] and '小明' not in attrs['tester']:
raise serializers.ValidationError('"小明"必须是leader或者tester')
return attrs
案例:
# 项目project表为父表("一"),接口表("多")为子表
class Interface(models.Model):
name = models.CharField(verbose_name='接口名', max_length=200, unique=True, help_text='接口名')
desc = models.TextField(verbose_name='简要描述', help_text='简要描述', blank=True, default='')
# 第一个参数为关联的模型路径(应用名.模型类)或者模型类
# 第二个参数设置得是,当父表删除后,该字段的处理方式
# CASCADE 子表也会删除,
# SET_NULL 当前外键值会被设置为None
# PROJECT 会报错
# SET_DEFAULT 设置默认值,同时需要指定默认值,null=True
project = models.ForeignKey('app01.Projects', on_delete=models.CASCADE, verbose_name='所属项目') class Meta:
db_table = 'tb_interface'
# 会在admin站点,显示更人性化的表名
verbose_name = '接口'
verbose_name_plural = '接口' # 在admin中显示名字
def __str__(self):
return self.name
model.py
数据库迁移命令
python manage.py makemigrations
python manage.py migrate
serializer.py
class HeroInfoSerializer(serializers.Serializer):
name = serializers.CharField(label="英雄的名字")
sex = serializers.CharField(label="性别", validators=[asster_django])
dsc = serializers.CharField(label="描述")
# hbook = serializers.PrimaryKeyRelatedField(label="书籍", read_only=True) # 只能获取
# PrimaryKeyRelatedField获取外键的ID
# hbook = serializers.PrimaryKeyRelatedField(label="书籍", queryset=Book.objects.all()) # 只能指定是Book中的书籍
# StringRelatedField获取外键的名字
# hbook = serializers.StringRelatedField(label="书籍")
# hbook = BookInfoSerializer() def validate_name(self, value):
if 'django' not in value.lower():
raise serializers.ValidationError('英雄名字中不包含django')
return value def validate(self, attrs):
if 'django' not in attrs['dsc'].lower():
raise serializers.ValidationError('dsc中不包含django') attrs['hello'] = '校验中新增'
return attrs
ModelSerializer序列化类定义
class ProjectsModelSerializer(serializers.ModelSerializer):
class Meta:
# 指定参考哪一个模型类创建
model = Projects
# 指定为模型类的哪些字段,来生产序列化器
fields = ‘__all__’
字段的约束条件设置
1、指定字段
fields = ('id', 'name', 'leader', 'tester', 'programer', 'publish_app')
2、不包含哪些字段
exclude = ('publish_app', 'desc')
3、指定哪些为只读字段
read_only_fields = ('publish_app', 'desc')
4、重写字段规则,具体规则和序列化一样
5、指定对应字段的约束条件 extra_kwargs ,注意 ️ :不是model中的,不可以在extra_kwargs 做限制
extra_kwargs = {
'leader':{
"write_only":True,
"max_length":200,
}
}
使用View获取视图数据
from django.views import View
1、如果返回的是数据集,要添加many=True,一条数据,直接传入就可以
2、序列化,传instance, 反序列化data
3、JsonResponse第一个默认参数是字典,如果不是要加JsonResponse(serializer.data,safe=False)
4、校验输入的数据
a、用序列化器对象的is_valid方法,才开始校验前端参数(校验成功返回true,错误返回False),raise_exception=True校验失败后会报出异常
b、调用is_valid之后才会调用errors。获取校验的提示(字典)
c、获取校验成功后的数据,可使用validated_data获取
5、如果一个序列化器传值 ProjectSerializer(instance=project, data=python_data)
a、只给一个data传值时,那么只会调用save(),就会调用create()
b、只给一个instance传值时,那么只会调用save(),就会调用update()
c、同时传两个值,会调用update()和create()
6、JsonResponse第一个默认参数是字典,如果不是要加JsonResponse(serializer.data,safe=False)
data = {
'name': "郭靖django",
'sex': '男性',
'dsc': 'django射雕英雄传人物',
'hbook_id': 1
}
serializer = HeroInfoSerializer(data=data)
serializer.is_valid()
serializer.is_valid(raise_exception=True)
serializer.errors
serializer.validated_data
serializer.save()
三、视图
前提:使用Django中的View,实现增删改查(序列化)
import json from django.views import View from DRF_Learn.models import Book
from django.http import JsonResponse, HttpResponse class BookListView(View):
def get(self, request):
books = Book.objects.all()
book_list = []
for book in books:
book_dict = {
'id': book.id,
'name': book.name,
'author': book.author,
'date_time': book.date_time
}
book_list.append(book_dict)
return JsonResponse(book_list, safe=False) def post(self, request):
book_dict = json.loads(request.body.decode())
book = Book(
name=book_dict['name'],
author=book_dict['author'],
date_time=book_dict['date_time']
)
book.save()
book_dict = {
'id': book.id,
'name': book.name,
'author': book.author,
'date_time': book.date_time
}
return JsonResponse(book_dict) class BookDetailView(View):
def get(self, request, pk):
try:
book = Book.objects.get(pk=pk)
except Book.DoesNotExist:
return HttpResponse({'message': "无数据"}, status=404)
book_dict = {
'id': book.id,
'name': book.name,
'author': book.author,
'date_time': book.date_time
}
return JsonResponse(book_dict) def put(self, request, pk):
try:
book = Book.objects.get(pk=pk)
except Book.DoesNotExist:
return HttpResponse({'message': "无数据"}, status=404)
book_dict = json.loads(request.body.decode())
book.name = book_dict['name']
book.author = book_dict['author']
book.date_time = book_dict['date_time']
book.save()
book_dict = {
"id": book.id,
"name": book.name,
"author": book.author,
"date_time": book.date_time
}
return JsonResponse(book_dict) def delete(self, request, pk):
try:
book = Book.objects.get(pk=pk)
except Book.DoesNotExist:
return HttpResponse({'message': "无数据"}, status=404)
book.delete()
return HttpResponse(status=202)
使用View实现增删改查
无序列化、视图View —> 增加序列化(Serializer,ModelSerializer),视图View —> 视图进阶为APIView —> 视图进阶为GenericAPIView —> GenericAPIView + Mixin合成类 —> ViewSet合并详情视图和List视图 —> GenericViewSet合并统一 —> 视图集(ReadOnlyModelViewSet、ModelViewSet)
1、View视图
serializer = HeroInfoSerializer(data=data)
serializer.is_valid() # 校验
serializer.is_valid(raise_exception=True)
serializer.error # 获取错误信息
serializer.validated_data # 获取处理后数据
serializer.save() # 调用增加或者更新方法
2、视图进阶为APIView
这时增加APIView,我们可以主要增加了获取数据request.data
,获取参数request.query_params。在返回数据增加了Response
。获取序列化后的数据使用serializer.data
,状态新增了status。
from rest_framework.views import APIView, Response, status data = request.data
serializer = BookInfoSerializer(data=data) Response(serializer.data)
3、视图进阶为GenericAPIView
主要增加了获取数据集和序列化
指定数据集和序列化
queryset = Book.objects.all()
serializer_class = BookInfoSerializer
获取数据集和序列化
self.get_queryset() 获取全数据集
self.get_object() 获取单一数据集
self.get_serializer 获取指定的序列化
4、GenericAPIView + Mixin合成类
<1>、继承ListModelMixin, CreateModelMixin, RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin 完成增删改查
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, DestroyModelMixin, \
UpdateModelMixin class BookListGenericAPIView(ListModelMixin, CreateModelMixin, GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookInfoSerializer def get(self, request):
# instance = self.get_queryset()
# serializer = self.get_serializer(instance, many=True)
return self.list(request) def post(self, request):
return self.create(request) class BookDetailGenericAPIView(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
queryset = Book.objects.all()
serializer_class = BookInfoSerializer def get(self, request, pk):
# instance = self.get_object()
# serializer = self.get_serializer(instance)
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)
<2>、继承ListModelMixin, CreateModelMixin, RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin完成增删改查
备注:这里继承的类中直接定义了get、post、put、delete所以可以不用再重新编辑方法。实际还是继承了ModelMixin的方法,所以要制定查询集和序列化器
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, DestroyModelMixin, \
UpdateModelMixin class BookListGenericAPIView(ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookInfoSerializer class BookDetailGenericAPIView(RetrieveUpdateDestroyAPIView):
queryset = Book.objects.all()
serializer_class = BookInfoSerializer
5、视图集
视图集
1、为了将???ListView和???DetailView两个方法写到一个类中,由于as_view指定路由时根据get和post等小写名来进行关联所以无法将这两类写到一个类中。
2、ViewSet视图集通过改变as_view的路由方式,创建了list、retrieve、destroy、put、create行为来重新做了定义。来实现写到一个类中。
一、定义路由
urlpatterns = [
# 视图集路由
path('', views.BookListGenericViewSet.as_view({'get': 'list', 'post': 'create'})),
path('<int:pk>/', views.BookListGenericViewSet.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}))
]
二、ViewSet
ViewSet视图集是继承APIView。
from rest_framework.viewsets import ViewSet, GenericViewSet
from .serializers import BookInfoSerializer
from rest_framework.response import Response
from .models import Book class BookListGenericViewSet(ViewSet): def list(self, request):
instance = Book.objects.all()
serializer = BookInfoSerializer(instance, many=True)
return Response(serializer.data) def create(self, request):
data = request.data
serializer = BookInfoSerializer(data=data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data) class BookDetailGenericViewSet(ViewSet):
def retrieve(self, request, pk):
instance = Book.objects.get(id=pk)
serialzier = BookInfoSerializer(instance)
return Response(serialzier.data) def update(self, request, pk):
instance = Book.objects.get(id=pk)
data = request.data
serializer = BookInfoSerializer(instance=instance, data=data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data) def destroy(self, request, pk):
instance = Book.objects.get(id=pk)
instance.delete()
return Response({'message': "删除成功"})
三、GenericViewSet
GenericViewSet继承GenericAPIView.
from rest_framework.viewsets import ViewSet, GenericViewSet
from .serializers import BookInfoSerializer
from rest_framework.response import Response
from .models import Book class BookListGenericViewSet(GenericViewSet):
queryset = Book.objects.all()
serializer_class = BookInfoSerializer def list(self, request):
instance = self.get_queryset()
serializer = self.get_serializer(instance, many=True)
return Response(serializer.data) def create(self, request):
data = request.data
serializer = self.get_serializer(data=data)
serializer.is_valid()
serializer.save()
return Response(serializer.data) class BookDetailGenericViewSet(GenericViewSet):
queryset = Book.objects.all()
serializer_class = BookInfoSerializer def retrieve(self, request, pk):
instance = self.get_object()
serializer = BookInfoSerializer(instance=instance)
return Response(serializer.data) def update(self, request, pk):
instance = self.get_object()
data = request.data
serializer = self.get_serializer(instance, data)
serializer.is_valid()
serializer.save()
return Response(serializer.data) def destroy(self, request, pk):
instance = self.get_object()
instance.delete()
return Response({'message': '删除成功'})
四、ReadOnlyModelViewSet
继承了RetrieveModelMixin、ListModelMixin、GenericViewSet。拥有了查单一和查所有的功能。
ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
mixins.ListModelMixin,
GenericViewSet):
五、ModelViewSet
继承了CreateModelMixin、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin、ListModelMixin、GenericViewSet。拥有了增删改查的功能。
ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet)
六、优化路由
历史:
from django.urls import path
from DRF_Learn import views urlpatterns = [
# 视图集ModelViewSet路由
path('', views.BookViewSet.as_view({'get': 'list', 'post': 'create'})),
path('<int:pk>/', views.BookViewSet.as_view({'get': 'retrieve', 'put': 'update', 'delete': 'destroy'}))
]
简化版:
from DRF_Learn import views
from rest_framework.routers import DefaultRouter urlpatterns = []
router = DefaultRouter() # 创建路由
router.register(r'', views.BookViewSet) # 注册路由
router.register(r'hero/', views.HeroViewSet) # 注册路由
urlpatterns += router.urls # 把生成好的路由拼接到urlpatterns
视图集
from rest_framework.viewsets import ModelViewSet, ReadOnlyModelViewSet
from .models import Book, Hero
from .serializers import BookInfoSerializer, HeroInfoSerializer class BookViewSet(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookInfoSerializer class HeroViewSet(ReadOnlyModelViewSet):
queryset = Hero.objects.all()
serializer_class = HeroInfoSerializer
HTTPResponse、JSONResponse和Response运用场景
HTTPResponse:
是由Django创造的,他的返回格式为:
HTTPResponse(content=响应体,content_type=响应体数据类型,status=状态码)、可以修改返回的数据类型,适用于返回图片,视频,音频等二进制文件。
JSONResponse:
JSONResponse是HTTPResponse的子类,适用于处理json格式的数据,但是不能返回模板。帮助我们将数据转换为json字符串、设置响应头Content-Type为application/json。
Response:
是Django rest-framework框架中封装好的响应对象。它的返回格式为:
Response(data,status=None,template_name=None,headers=None,content_type=None),data只需传递Python的内建类型数据即可,如果是Django的模型类对象,那么就是用序列化数据(Python的字典数据)传递给data。
render和redirect:
render 返回页面内容(渲染变量到模板中),并且没有发送第二次请求
redirect 发送了第二次请求,是个跳转函数,一般跳转到外部网站,而且会返回302的状态码
此外:
- render 参数一般为模板html文件
- redirect 参数一般为URL地址
DRF全局总结的更多相关文章
- django DRF理解
django restframework(DRF) 最近的开发过程当中,发现restframework的功能很强大,所以尝试解读了一下源码,写篇博客分享给大家,有错误的地方还请各位多多指出 视图部分 ...
- Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程
一.序列化类的增.删.改.查 用drf的序列化组件 -定义一个类继承class BookSerializer(serializers.Serializer): -写字段,如果不指定source ...
- drf相关问题
drf自定义用户认证: 登录默认 使用django的ModelBackend,对用户名和密码进行验证.但我们平时登录网站时除了用户名也可以用邮箱或手机进行登录,这就需要我们自己扩展backend 一. ...
- DRF项目创建流程(1)
一 web应用模式 前后端不分离 前后端分离 二 RESTFUL API规范 REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态 ...
- DRF初识与序列化
一.Django的序列化方法 1.为什么要用序列化组件 做前后端分离的项目,我们前后端数据交互一般都选择JSON,JSON是一个轻量级的数据交互格式.那么我们给前端数据的时候都要转成json格式,那就 ...
- DRF之版本控制、认证和权限组件
一.版本控制组件 1.为什么要使用版本控制 首先我们开发项目是有多个版本的当我们项目越来越更新,版本就越来越多,我们不可能新的版本出了,以前旧的版本就不进行维护了像bootstrap有2.3.4版本的 ...
- DRF之频率限制、分页、解析器和渲染器
一.频率限制 1.频率限制是做什么的 开放平台的API接口调用需要限制其频率,以节约服务器资源和避免恶意的频繁调用. 2.频率组件原理 DRF中的频率控制基本原理是基于访问次数和时间的,当然我们可以通 ...
- drf视图组件、认证组件
视图组件 1.基本视图 url(r'^publish/$', views.PublishView.as_view()), url(r'^publish/(?P<pk>\d+)/$', vi ...
- DRF 认证、权限、限制
DRF 认证.权限.限制 认证: 定义一个用户表和一个保存用户的Token表 # ======================day96======================= class ...
- DRF框架之 用户角色权限与访问频率的权限设置
1. 简单演示,创建一个models的数据库表 class User(models.Model): name=models.CharField(max_length=32) pwd=models.Ch ...
随机推荐
- last-child可能你也会踩的坑
旧文章从语雀迁移过来,原日期为2021-07-14 问题 当时写在写一个列表,列表每一项需要下面加下划线,最后一项不加下划线.第一时间,想到使用 :``last-child 这个伪类来实现. 当时的代 ...
- 把ChatGPT配置到微信群里,可以对AI提问了!
作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言:用的很爽! 自从小傅哥用上 ChatGPT 连搜索引擎用的都不多了,很多问题的检索我 ...
- Service层和Dao层的一些自我理解(╥╯^╰╥)(╥╯^╰╥)(学了这么久,这玩意儿似懂非懂的)
学习java已经有很长时间了,但由于是在学校学的,基础不怎么扎实. 这几个月系统的学习,弥补了很多的缺陷,虽然大多数时间都在弄算法(咳咳),我前面的博客有写 如果有认真看过我代码的朋友会发现,我其实英 ...
- [python] 基于Gradio可视化部署机器学习应用
Gradio是一个开源的Python库,用于构建机器学习和数据科学演示应用.有了Gradio,你可以围绕你的机器学习模型或数据科学工作流程快速创建一个简单漂亮的用户界面.Gradio适用于以下情况: ...
- 真正“搞”懂HTTP协议07之队头阻塞真的很烦人
这一篇文章,我们核心要聊的事情就是HTTP的对头阻塞问题,因为HTTP的核心改进其实就是在解决HTTP的队头阻塞.所以,我们会讲的理论多一些,而实践其实很少,要学习的头字段也只有一个,我会在最开始就讲 ...
- 可持久化栈学习笔记 | 题解 P6182 [USACO10OPEN]Time Travel S
简要题意 你需要维护一个栈,有 \(n\) 个操作,支持: 给定一个 \(x\),将 \(x\) 加入栈. 将一个元素出栈. 给定一个 \(x\),将当前栈回退到 第 \(x\) 操作前. 每一次操作 ...
- MySQL 删除数据 批量删除(大量)数据
在删除数据的时候根据不同的场景使用不同的方法,比如说删除表中部分数据.删除表的结构.删除所有记录并重置自增ID.批量删除大量数据等,可以使用delete.truncate.drop等语句. 一.方法分 ...
- web应用开发模式、API接口、接口测试工具postman
web应用开发模式.API接口.接口测试工具postman web开发模式 前后端混合开发模式 前后端混合开发模式是指前后端代码混合,所有的HTML代码和数据在服务器端拼接好,一次性将内容发送到客户端 ...
- C# 线程查漏补缺
进程和线程 不同程序执行需要进行调度和独立的内存空间 在单核计算机中,CPU 是独占的,内存是共享的,这时候运行一个程序的时候是没有问题.但是运行多个程序的时候,为了不发生一个程序霸占整个 CPU 不 ...
- 如何又快又好实现 Catalog 系统搜索能力?火山引擎 DataLeap 这样做
摘要 DataLeap 是火山引擎数智平台 VeDI 旗下的大数据研发治理套件产品,帮助用户快速完成数据集成.开发.运维.治理.资产.安全等全套数据中台建设,降低工作成本和数据维护成本.挖掘数据价 ...