Django-rest Framework(五)
把十大接口做完了才能更好的了解后面的视图类
1.(重点)二次封装Response;自定义APIResponse继承Response,重写 ____init____方法
from rest_framework.response import Response #导入Response类
class APIResponse(Response): #继承Response类
def __init__(self,status=0,msg='ok',results=None,http_status=None,headers=None,exception=None,**kwargs): #重写__init__方法
data = {
'status':status,
'msg':msg
}
if results is not None:
data['result'] = results
data.update(**kwargs) #接收其他多余参数
# 再使用父类的__init__方法
super().__i
2.(正常)在orm的模型表中,设置了abstract为True的模型类,称之为基类,这样的模型类是专门作为基类来提供公有属性的(基类不会参与数据迁移)
class BaseModel(models.Model): #继承基础模型类
is_delete = models.BooleanField() #创建公共属性
create_time = models.DateTimeField(auto_now_add=True) #创建公共属性
class Meta:
abstract:True # 声明为基类
class xxx(BaseModel) # 其他类继承基类
3.(重点)ORM多表关联操作(以书籍表 作者表 出版社表 作者详情表为例):
外键所放的位置
一对多 : 外键放在多的那一方(出版社,书籍)
class Book(BaseModel):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=9,decimal_places=2)
'''
related_name='books' : 设置反向查询为books
db_constraint=False : 断开外键约束
on_delete=models.DO_NOTHING(在外键数据没有的情况下,任然保持数据 出版社没了,书还是 那个出版社出版)
''' publish=models.ForeignKey(to='Publish',related_name='books',db_constraint=False,on_delete=models.DO_NOTHING)
# 多对多字段 断约束 设置反向查询名字
author = models.ManyToManyField(to='Author',db_constraint=False,related_name='books') class Publish(BaseModel):
name = models.CharField(max_length=32)
addres = models.CharField(max_length=32)
多对多:外键放在常用的一方(书 ,作者)
class Book(BaseModel):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=9,decimal_places=2)
'''
related_name='books' : 设置反向查询为books
db_constraint=False : 断开外键约束
on_delete=models.DO_NOTHING(在外键数据没有的情况下,任然保持数据 出版社没了,书还是那个出版社出版)
'''
publish = models.ForeignKey(to='Publish',related_name='books',db_constraint=False,on_delete=models.DO_NOTHING)
# 多对多字段 断约束 设置反向查询名字
author=models.ManyToManyField(to='Author',db_constraint=False,related_name='books')
3.一对一 : 外键放在不长用的那一方
class Book(BaseModel):
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=9,decimal_places=2)
'''
related_name='books' : 设置反向查询为books
db_constraint=False : 断开外键约束
on_delete=models.DO_NOTHING(在外键数据没有的情况下,任然保持数据 出版社没了,书还是那个 出版社出版)
'''
publish = models.ForeignKey(to='Publish',related_name='books',db_constraint=False,on_delete=models.DO_NOTHING)
# 多对多字段 断约束 设置反向查询名字
author = models.ManyToManyField(to='Author',db_constraint=False,related_name='books')外键字段为正向查询字段,related_name是反向查询字段
2.如何断外键关联
设置外键字段db_constraint=False
3.外键之间的级联关系
- 一对一 : 作者没了,详情也没了 : on_delete=models.CASEADE
- 一对多 : 出版社没了,书还是那个出版社出版:on_delete=models.DO_ONTHING
- 一对多 : 部门没了 ,员工没有部门(空部门) :null=True ,on_delete=models.SET_NULL
- 一对多 : 部门没了,员工进入默认部门(默认值) : default=0, on_delete=models.SET_DEFAULT
- 多对多 : 不能设置 on_delete
4.(重点)连表序列化,在model类中定义插拔序列化方法属性,完成连表查询
@property
def author_detail(self):
author_queryset = self.authors.all() #查询出所有的作者
author_detail = []
for author_obj in author_queryset:
author_detail.append(
{
'name': author_obj.name,
'sex':author_obj.get_sex_display(),
'mobile':author_obj.detail.mobile
}
)
return author_detail #返回作者列表信息
5.(正常) 子序列化可以辅助快速实现自定义外键深度的序列化,但是不能完成反序列化
# 前提 : 如果只有查需求的接口,自定义深度还可以用子序列化方式完成
class PublishSerilizer(ModelSerializer):
# 子序列化都是提供外键(正方向)完成深度查询的,外键数据是唯一:many=Falise 不唯一 many=True
#注 : 只能参与序列化,且反序列化不能写(反序列化外键字段会抛异常)
books = BookSerializer(many=True)
class Meta:
model = models.Publish
fields = ['name','address','books']
6.(重要) 单查 群查接口,序列化类提供序列化对象,many参数控制着操作的数据是一条还是多条
7.(正常)单删 群删接口,后台操作删除字段即可,前端提供pk为单删,提供pks就是群删
# 单删 群删
def delete(self,request,*args,**kwargs):
pk = kwargs.get('pk')
if pk:
pks = [pk]
else:
pks = request.data.get('pks')
row = models.Book.objects.filter(is_delete=False,pk__in=pks).update(is_delete=True)
if row:
return APIResponse.APIResponse(msg='delete ok')
return APIResponse.APIResponse(status=1,msg='delete error')
8.(重点) 单增群增接口,根据数据判断是单增还是群增,对应序列化类要设置many,而序列化只需要通过data即可
# 单增 群增
def post(self,request,*args,**kwargs):
request_data = request.data
if isinstance(request_data,dict) and len(request_data) !=0:
book_ser = Serializers.BookSerializer(data=request_data,many=False)
if book_ser.is_valid(raise_exception=True):
book_obj = book_ser.save()
return APIResponse.APIResponse(results=Serializers.BookSerializer(book_obj,many=False).data)
else:
return APIResponse.APIResponse(results=book_ser.errors)
elif isinstance(request_data,list) and len(request_data) !=0:
book_ser = Serializers.BookSerializer(data=request_data, many=True)
if book_ser.is_valid(raise_exception=True):
book_obj_list = book_ser.save()
return APIResponse.APIResponse(results=Serializers.BookSerializer(book_obj_list,many=True).data)
else:
return APIResponse.APIResponse(results=book_ser.errors)
else:
return APIResponse.APIResponse(1,'add error')
9.(正常)单整体改群整体改,前端提供的数据,后台要转化成要修改的对象们和用来更新的数据们,ModelSerializser设置 list_serializesr_class关联自己的ListSerializer,重新update()方法,完成群该
# 单整体改 群整体改
def put(self,request,*args,**kwargs):
request_data = request.data
pk = kwargs.get('pk')
if pk:
try:
book_obj = models.Book.objects.get(pk=pk)
print(pk)
print(book_obj)
except:
return APIResponse.APIResponse(1,'update error')
book_ser = Serializers.BookSerializer(instance=book_obj,data=request_data)
book_ser.is_valid(raise_exception=True)
res_obj = book_ser.save()
return APIResponse.APIResponse(results=Serializers.BookSerializer(res_obj).data)
elif isinstance(request_data,list) and len(request_data) !=0:
obj_list = []
data_list = []
for dic in request_data:
try:
pk = dic.pop('pk')
try:
obj = models.Book.objects.filter(pk=pk).first()
obj_list.append(obj)
data_list.append(dic)
except:
pass
except:
return APIResponse.APIResponse(1,'update error')
book_ser_list = Serializers.BookSerializer(instance=obj_list,data=data_list,many=True)
book_ser_list.is_valid(raise_exception=True)
book_res_list = book_ser_list.save()
return APIResponse.APIResponse(results=Serializers.BookSerializer(book_res_list,many=True).data)
else:
return APIResponse.APIResponse(http_status=400,status=1,msg='update error')
10.(正常) 单局部改,序列化参数instance=修改的对象,data=修改的数据,partial=能否能局部修改,单整体改就是partial=False (默认就是False)
# 单局部改 群局部改
def patch(self, request, *args, **kwargs):
request_data = request.data
pk = kwargs.get('pk')
if pk:
try:
book_obj = models.Book.objects.get(pk=pk)
except:
return APIResponse.APIResponse(1, 'update error')
book_ser = Serializers.BookSerializer(instance=book_obj, data=request_data,partial=True)
book_ser.is_valid(raise_exception=True)
res_obj = book_ser.save()
return APIResponse.APIResponse(results=Serializers.BookSerializer(res_obj).data)
elif isinstance(request_data, list) and len(request_data) != 0:
obj_list = []
data_list = []
for dic in request_data:
try:
pk = dic.pop('pk')
try:
obj = models.Book.objects.filter(pk=pk).first()
obj_list.append(obj)
data_list.append(dic)
except:
pass
except:
return APIResponse.APIResponse(1, 'update error')
book_ser_list = Serializers.BookSerializer(instance=obj_list, data=data_list, many=True,partial=True)
book_ser_list.is_valid(raise_exception=True)
book_res_list = book_ser_list.save()
return APIResponse.APIResponse(results=Serializers.BookSerializer(book_res_list, many=True).data)
else:
return APIResponse.APIResponse(http_status=400, status=1, msg='update error')
异常模块代码:
from rest_framework.response import Response #导入Response类
class APIResponse(Response): #继承Response类
def __init__(self,status=0,msg='ok',results=None,http_status=None,headers=None,exception=None,**kwargs): #重写__init__方法
data = {
'status':status,
'msg':msg
}
if results is not None:
data['result'] = results
data.update(**kwargs) #接收其他多余参数
# 再使用父类的__init__方法
super().__init__(data=data,status=http_status,headers=headers,exception=exception)
orm models代码:
from django.db import models
from django.conf import settings
# 一、基表
# Model类的内部配置Meta类要设置abstract=True,这样的Model类就是用来作为基表
# 多表:Book,Publish,Author,AuthorDetail
class BaseModel(models.Model):
is_delete = models.BooleanField(default=False)
create_time = models.DateTimeField(auto_now_add=True)
class Meta:
# 基表必须设置abstract,基表就是给普通Model类继承使用的,设置了abstract就不会完成数据库迁移完成建表
abstract = True
class Book(BaseModel):
name = models.CharField(max_length=16)
price = models.DecimalField(max_digits=5, decimal_places=2)
publish = models.ForeignKey(to='Publish', related_name='books', db_constraint=False, on_delete=models.DO_NOTHING)
# 重点:多对多外键实际在关系表中,ORM默认关系表中两个外键都是级联
# ManyToManyField字段不提供设置on_delete,如果想设置关系表级联,只能手动定义关系表
authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False)
@property
def author_detail(self):
author_queryset = self.authors.all()
author_detail = []
for author_obj in author_queryset:
author_detail.append(
{
'name': author_obj.name,
'sex':author_obj.get_sex_display(),
'mobile':author_obj.detail.mobile
}
)
return author_detail
class Meta:
verbose_name_plural = '书籍表'
def __str__(self):
return self.name
class Publish(BaseModel):
name = models.CharField(max_length=16)
address = models.CharField(max_length=64)
class Meta:
verbose_name_plural = '出版社表'
def __str__(self):
return self.name
class Author(BaseModel):
name = models.CharField(max_length=16)
sex = models.IntegerField(choices=[(0, '男'),(1, '女')], default=0)
class Meta:
verbose_name_plural='作者表'
def __str__(self):
return self.name
class AuthorDetail(BaseModel):
mobile = models.CharField(max_length=11)
# 有作者可以没有详情,删除作者,详情一定会被级联删除
# 外键字段为正向查询字段,related_name是反向查询字段
author = models.OneToOneField(to='Author', related_name='detail', db_constraint=False, on_delete=models.CASCADE)
序列化代码:
from rest_framework import serializers
from rest_framework.serializers import ModelSerializer
from . import models
class BookListSerializer(serializers.ListSerializer):
def update(self, instance, validated_data):
return [
self.child.update(instance[i],attrs) for i,attrs in validated_data
]
class BookSerializer(ModelSerializer):
class Meta:
model = models.Book
list_serializes_class = BookListSerializer
fields = ['name','price','author_detail','publish','authors']
extra_kwargs = {
'publish':{
'write_only':True
},
'authors':{
'write_only':True
}
}
class PublishSerilizer(ModelSerializer):
books = BookSerializer(many=True)
class Meta:
model = models.Publish
fields = ['name','address','books']
Django-rest Framework(五)的更多相关文章
- Django REST framework 五种增删改查方法
Django-DRF-视图的演变 版本一(基于类视图APIView类) views.py: APIView是继承的Django View视图的. 1 from .serializers impor ...
- Django REST framework+Vue 打造生鲜超市(五)
六.商品类别数据展示 6.1. 商品类别数据接口 (1)商品分类有两个接口: 一种是全部分类:一级二级三级 一种是某一类的分类以及商品详细信息: 开始写商品分类的接口 (2)序列化 给分类添加三级分类 ...
- Django Rest Framework源码剖析(五)-----解析器
一.简介 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数据格式,比如xml,所以需要解析这类数 ...
- Django REST framework+Vue 打造生鲜超市(一)
一.项目介绍 1.1.掌握的技术 Vue + Django Rest Framework 前后端分离技术 彻底玩转restful api 开发流程 Django Rest Framework 的功能实 ...
- Django REST framework+Vue 打造生鲜超市(三)
四.xadmin后台管理 4.1.xadmin添加富文本插件 (1)xadmin/plugins文件夹下新建文件ueditor.py 代码如下: # xadmin/plugins/ueditor.py ...
- Django REST framework+Vue 打造生鲜超市(四)
五.商品列表页 5.1.django的view实现商品列表页 (1)goods/view_base.py 在goods文件夹下面新建view_base.py,为了区分django和django res ...
- Django REST framework+Vue 打造生鲜超市(十二)
十三.首页.商品数量.缓存和限速功能开发 13.1.轮播图接口实现 首先把pycharm环境改成本地的,vue中local_host也改成本地 (1)goods/serializer class B ...
- Django rest framework源码分析(1)----认证
目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...
- 01 Django REST Framework 介绍
01-Django REST Framework的介绍 Django REST框架是一个用于构建Web API的强大而灵活的工具包. 您可能希望使用REST框架的一些原因: 1. Web可浏览API对 ...
- Django Rest framework 框架
一.开发模式: 1. 普通开发方式(前后端放在一起写) 2. 前后端分离(前后台通过ajaxo交互) 后端(django rest framework写的) <----ajaxo---> ...
随机推荐
- csdn自动生成目录索引、插入代码片快捷键
文章目录 自动生成目录索引 插入代码片 自动生成目录索引 文章开头加入 @[TOC](目录描述) 目录描述可不写 插入代码片 cmd/ctrl + shift + k
- ELK5.2+kafka+zookeeper+filebeat集群部署
架构图 考虑到日志系统的可扩展性以及目前的资源(部分功能复用),整个ELK架构如下: 架构解读 : (整个架构从左到右,总共分为5层) 第一层.数据采集层 最左边的是业务服务器集群,上面安装了file ...
- 第十五篇:java操作oracle踩坑之旅
最近刚做完mysql的各种需求,项目要满足oracle数据库,于是走上了漫漫的踩坑之路,同行可以看看以免踩坑……第一条:oracle建表的时候不需要在建表sql语句后指定默认字符集 DEFAULT C ...
- 第一篇:spring+springMVC项目启动最终笔记(一web.xml)
1.web应用启动从web.xml开始,首先创建一个全局的上下文(Context),名字叫ServletContext,可以理解为一间图书馆,或一个数据结构(如map,但是比map牛多了),整个结构类 ...
- 【LGP5350】序列
题目 可能\(\operatorname{fhq\ treap}\)能做,但是珂朵莉树显然更好写 珂朵莉树是个很玄学的东西啊,就是直接使用\(\operatorname{std::set}\)维护每一 ...
- 侧滑关闭Activity的解决方案——SwipeBackLayout
项目地址:ikew0ng/SwipeBackLayout: An Android library that help you to build app with swipe back gesture. ...
- amazeUI tab禁止左右滑动(触控操作)
参考:http://amazeui.clouddeep.cn/javascript/tabs/ 效果: html: <!DOCTYPE html> <html> <hea ...
- rsyslog 服务器重启后 发现不能接受到外部日志 只能接受本地日志 关闭防火墙即可
rsyslog 服务器重启后 发现不能接受到外部日志 只能接受本地日志 关闭防火墙即可 1 关闭防火墙: # systemctl stop firewalld 2 将SELINUX设置为disabl ...
- 便携版Mysql安装
目录 1.安装 0.Mysql下载地址 1.解压 2.在主目录下新建data和tempData两个文件夹 3.配置环境变量 4.配置my.ini 5.安装服务(管理员模式CMD) 6.清空data文件 ...
- Python-基本运算符与流程控制
目录 基本运算符 算术运算符 比较运算符 赋值运算符 逻辑运算符 身份运算符 位运算符 成员运算符 运算符优先级 流程控制 if 判断 单分支结构 双分支结构 多分支结构 while 循环 while ...