基础部分

一、创建工程

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全局总结的更多相关文章

  1. django DRF理解

    django restframework(DRF) 最近的开发过程当中,发现restframework的功能很强大,所以尝试解读了一下源码,写篇博客分享给大家,有错误的地方还请各位多多指出 视图部分 ...

  2. Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程

    一.序列化类的增.删.改.查 用drf的序列化组件   -定义一个类继承class BookSerializer(serializers.Serializer):   -写字段,如果不指定source ...

  3. drf相关问题

    drf自定义用户认证: 登录默认 使用django的ModelBackend,对用户名和密码进行验证.但我们平时登录网站时除了用户名也可以用邮箱或手机进行登录,这就需要我们自己扩展backend 一. ...

  4. DRF项目创建流程(1)

    一 web应用模式 前后端不分离 前后端分离 二 RESTFUL API规范 REST全称是Representational State Transfer,中文意思是表述(编者注:通常译为表征)性状态 ...

  5. DRF初识与序列化

    一.Django的序列化方法 1.为什么要用序列化组件 做前后端分离的项目,我们前后端数据交互一般都选择JSON,JSON是一个轻量级的数据交互格式.那么我们给前端数据的时候都要转成json格式,那就 ...

  6. DRF之版本控制、认证和权限组件

    一.版本控制组件 1.为什么要使用版本控制 首先我们开发项目是有多个版本的当我们项目越来越更新,版本就越来越多,我们不可能新的版本出了,以前旧的版本就不进行维护了像bootstrap有2.3.4版本的 ...

  7. DRF之频率限制、分页、解析器和渲染器

    一.频率限制 1.频率限制是做什么的 开放平台的API接口调用需要限制其频率,以节约服务器资源和避免恶意的频繁调用. 2.频率组件原理 DRF中的频率控制基本原理是基于访问次数和时间的,当然我们可以通 ...

  8. drf视图组件、认证组件

    视图组件 1.基本视图 url(r'^publish/$', views.PublishView.as_view()), url(r'^publish/(?P<pk>\d+)/$', vi ...

  9. DRF 认证、权限、限制

    DRF 认证.权限.限制   认证: 定义一个用户表和一个保存用户的Token表 # ======================day96======================= class ...

  10. DRF框架之 用户角色权限与访问频率的权限设置

    1. 简单演示,创建一个models的数据库表 class User(models.Model): name=models.CharField(max_length=32) pwd=models.Ch ...

随机推荐

  1. MongoDB 索引原理与索引优化

    转载请注明出处: 1.MongoDB索引 索引通常能够极大的提高查询的效率, 如果没有索引, MongoDB 在读取数据时必须扫描集合中的每个文件并选取那些符合查询条件的记录.这种扫描全集合的查询效率 ...

  2. 就聊聊不少小IT公司的技术总监

    本文想告诉大家如下两个观点. 1 很多IT小公司的技术总监,论能力其实也就是相当于大公司的高级程序员. 2 程序员在职业发展过程中,绝对应该优先考虑进大厂或好公司.如果仅仅停留在小公司,由于小公司可能 ...

  3. [python]《Python编程快速上手:让繁琐工作自动化》学习笔记4

    1. 处理Excel 电子表格笔记(第12章)(代码下载) 本文主要介绍openpyxl 的2.5.12版处理excel电子表格,原书是2.1.4 版,OpenPyXL 团队会经常发布新版本.不过不用 ...

  4. Mariadb对数据库和表的操作

    登录mariadb: 路径切换到bin下 mysql -u root -p 然后会提示输密码 新建数据库: create database demo; 其中demo为数据库名字 新建表 create ...

  5. AcWing第85场周赛

    这场周赛是手速局hh 死或生 某国正在以投票的方式决定 2 名死刑犯(编号 1∼2)的生死. 共有 n 组人员(编号 1∼n)参与投票,每组 10 人. 每组成员只参与一名死刑犯的投票,其中第 i 组 ...

  6. BatteryStatsHelper.java源码分析

    在分析PowerUsageSummary的时候,其实可以发现主要获取应用和服务电量使用情况的实现是在BatteryStatsHelper.java中 还是在线网站http://androidxref. ...

  7. dfs 返回值用bool相对void会快一点

    力扣 剑指 Offer 12. 矩阵中的路径 超时代码 dfs返回值是void,用类内的全局变量flag表示找到或没找到. class Solution { public: bool flag; in ...

  8. vs code 关联gitee码云或github以及GIT 常用命令

    一.准备 1.本地安装vs code 和GIT源代码管理工具 2.配置vscode git全局变量 打开左下角设置-->点击用户-->搜索git.path-->settings.js ...

  9. P8_组件-view和scroll-view组件的基本用法

    组件 小程序中组件的分类 小程序中的组件也是由宿主环境提供的,开发者可以基于组件快速搭建出漂亮的页面结构.官方把小程序的组件分为了 9 大类,分别是: 视图容器 基础内容 表单组件 导航组件 媒体组件 ...

  10. jquery(一:认识jquery、选择器)

    jQuery 优点: 1.提供了强大的功能函数 2.解决了浏览器的兼容问题 3.实现了丰富的UI和插件 4.纠正错误的脚本知识 例子 1.传统: <!DOCTYPE html> <h ...