把十大接口做完了才能更好的了解后面的视图类

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多表关联操作(以书籍表 作者表 出版社表 作者详情表为例):

  1. 外键所放的位置

    1. 一对多 : 外键放在多的那一方(出版社,书籍)

      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)
    2. 多对多:外键放在常用的一方(书 ,作者)

      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.外键之间的级联关系

  1. 一对一 : 作者没了,详情也没了 : on_delete=models.CASEADE
  2. 一对多 : 出版社没了,书还是那个出版社出版:on_delete=models.DO_ONTHING
  3. 一对多 : 部门没了 ,员工没有部门(空部门) :null=True ,on_delete=models.SET_NULL
  4. 一对多 : 部门没了,员工进入默认部门(默认值) : default=0, on_delete=models.SET_DEFAULT
  5. 多对多 : 不能设置 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']

最新文章

  1. 页面与ViewModel(上)
  2. JavaScript 数组
  3. bzoj1202--带权并查集+前缀和
  4. 【BZOJ-1086】王室联邦 分块 + 块状树
  5. Shader 之 顶点变形
  6. 分享一段视频关于SQL2014 Hekaton数据库的
  7. ps中如何用抽出功能扣取头发
  8. 重要选择器querySelector和querySelectorAll
  9. CSS3 transforms 3D翻开
  10. Java Web Service 学习
  11. FCKEditor文件上传提示信息的汉化
  12. where group by联合使用
  13. 怎么修改tomcat默认访问首页
  14. jQuery HighchartsTableHTML表格转Highcharts图表插件
  15. linux添加新硬盘并格式化
  16. 1.2 decimal模块
  17. left join 右表数据不唯一的情况解决方法
  18. python --help查询python相关命令
  19. sublime text3 配置
  20. x为正变数,求y=x^3/(x^4+4)的最大值

热门文章

  1. FastJSON实现详解
  2. sessionStorage 和 localStorage的区别
  3. 接着上回,导包正确之后,出现javabean.Friend cannot be cast to java.util.List,的错误。找了很久。以为是User user0作为参数,改成了String username还是错误,看了看listFriend.jsp没有错误,我想会不会是包多了,导致类型复杂。最后发现包少了一个:
  4. 03_mybatis配置文件详解
  5. 小程序开发之wepy框架
  6. Java中9大内置基本数据类型Class实例和数组的Class实例
  7. wpf 让正执行的程序暂停几秒钟
  8. js 实现vue—引入子组件props传参
  9. sql 分组统计查询并横纵坐标转换
  10. leetcode-154-寻找旋转排序数组中的最小值