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

1.(重点)二次封装Response;自定义APIResponse继承Response,重写 ____init____方法

  1. from rest_framework.response import Response #导入Response类
  2. class APIResponse(Response): #继承Response类
  3. def __init__(self,status=0,msg='ok',results=None,http_status=None,headers=None,exception=None,**kwargs): #重写__init__方法
  4. data = {
  5. 'status':status,
  6. 'msg':msg
  7. }
  8. if results is not None:
  9. data['result'] = results
  10. data.update(**kwargs) #接收其他多余参数
  11. # 再使用父类的__init__方法
  12. super().__i

2.(正常)在orm的模型表中,设置了abstract为True的模型类,称之为基类,这样的模型类是专门作为基类来提供公有属性的(基类不会参与数据迁移)

  1. class BaseModel(models.Model): #继承基础模型类
  2. is_delete = models.BooleanField() #创建公共属性
  3. create_time = models.DateTimeField(auto_now_add=True) #创建公共属性
  4. class Meta:
  5. abstract:True # 声明为基类
  6. class xxx(BaseModel) # 其他类继承基类

3.(重点)ORM多表关联操作(以书籍表 作者表 出版社表 作者详情表为例):

  1. 外键所放的位置

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

      1. class Book(BaseModel):
      2. name = models.CharField(max_length=32)
      3. price = models.DecimalField(max_digits=9,decimal_places=2)
      4. '''
      5. related_name='books' : 设置反向查询为books
      6. db_constraint=False : 断开外键约束
      7. on_delete=models.DO_NOTHING(在外键数据没有的情况下,任然保持数据 出版社没了,书还是 那个出版社出版)
      8. ''' publish=models.ForeignKey(to='Publish',related_name='books',db_constraint=False,on_delete=models.DO_NOTHING)
      9. # 多对多字段 断约束 设置反向查询名字
      10. author = models.ManyToManyField(to='Author',db_constraint=False,related_name='books')
      11. class Publish(BaseModel):
      12. name = models.CharField(max_length=32)
      13. addres = models.CharField(max_length=32)
    2. 多对多:外键放在常用的一方(书 ,作者)

      1. class Book(BaseModel):
      2. name = models.CharField(max_length=32)
      3. price = models.DecimalField(max_digits=9,decimal_places=2)
      4. '''
      5. related_name='books' : 设置反向查询为books
      6. db_constraint=False : 断开外键约束
      7. on_delete=models.DO_NOTHING(在外键数据没有的情况下,任然保持数据 出版社没了,书还是那个出版社出版)
      8. '''
      9. publish = models.ForeignKey(to='Publish',related_name='books',db_constraint=False,on_delete=models.DO_NOTHING)
      10. # 多对多字段 断约束 设置反向查询名字
      11. author=models.ManyToManyField(to='Author',db_constraint=False,related_name='books')

    3.一对一 : 外键放在不长用的那一方

    1. class Book(BaseModel):
    2. name = models.CharField(max_length=32)
    3. price = models.DecimalField(max_digits=9,decimal_places=2)
    4. '''
    5. related_name='books' : 设置反向查询为books
    6. db_constraint=False : 断开外键约束
    7. on_delete=models.DO_NOTHING(在外键数据没有的情况下,任然保持数据 出版社没了,书还是那个 出版社出版)
    8. '''
    9. publish = models.ForeignKey(to='Publish',related_name='books',db_constraint=False,on_delete=models.DO_NOTHING)
    10. # 多对多字段 断约束 设置反向查询名字
    11. 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类中定义插拔序列化方法属性,完成连表查询

  1. @property
  2. def author_detail(self):
  3. author_queryset = self.authors.all() #查询出所有的作者
  4. author_detail = []
  5. for author_obj in author_queryset:
  6. author_detail.append(
  7. {
  8. 'name': author_obj.name,
  9. 'sex':author_obj.get_sex_display(),
  10. 'mobile':author_obj.detail.mobile
  11. }
  12. )
  13. return author_detail #返回作者列表信息

5.(正常) 子序列化可以辅助快速实现自定义外键深度的序列化,但是不能完成反序列化


  1. # 前提 : 如果只有查需求的接口,自定义深度还可以用子序列化方式完成
  2. class PublishSerilizer(ModelSerializer):
  3. # 子序列化都是提供外键(正方向)完成深度查询的,外键数据是唯一:many=Falise 不唯一 many=True
  4. #注 : 只能参与序列化,且反序列化不能写(反序列化外键字段会抛异常)
  5. books = BookSerializer(many=True)
  6. class Meta:
  7. model = models.Publish
  8. fields = ['name','address','books']

6.(重要) 单查 群查接口,序列化类提供序列化对象,many参数控制着操作的数据是一条还是多条

7.(正常)单删 群删接口,后台操作删除字段即可,前端提供pk为单删,提供pks就是群删

  1. # 单删 群删
  2. def delete(self,request,*args,**kwargs):
  3. pk = kwargs.get('pk')
  4. if pk:
  5. pks = [pk]
  6. else:
  7. pks = request.data.get('pks')
  8. row = models.Book.objects.filter(is_delete=False,pk__in=pks).update(is_delete=True)
  9. if row:
  10. return APIResponse.APIResponse(msg='delete ok')
  11. return APIResponse.APIResponse(status=1,msg='delete error')

8.(重点) 单增群增接口,根据数据判断是单增还是群增,对应序列化类要设置many,而序列化只需要通过data即可

  1. # 单增 群增
  2. def post(self,request,*args,**kwargs):
  3. request_data = request.data
  4. if isinstance(request_data,dict) and len(request_data) !=0:
  5. book_ser = Serializers.BookSerializer(data=request_data,many=False)
  6. if book_ser.is_valid(raise_exception=True):
  7. book_obj = book_ser.save()
  8. return APIResponse.APIResponse(results=Serializers.BookSerializer(book_obj,many=False).data)
  9. else:
  10. return APIResponse.APIResponse(results=book_ser.errors)
  11. elif isinstance(request_data,list) and len(request_data) !=0:
  12. book_ser = Serializers.BookSerializer(data=request_data, many=True)
  13. if book_ser.is_valid(raise_exception=True):
  14. book_obj_list = book_ser.save()
  15. return APIResponse.APIResponse(results=Serializers.BookSerializer(book_obj_list,many=True).data)
  16. else:
  17. return APIResponse.APIResponse(results=book_ser.errors)
  18. else:
  19. return APIResponse.APIResponse(1,'add error')

9.(正常)单整体改群整体改,前端提供的数据,后台要转化成要修改的对象们和用来更新的数据们,ModelSerializser设置 list_serializesr_class关联自己的ListSerializer,重新update()方法,完成群该

  1. # 单整体改 群整体改
  2. def put(self,request,*args,**kwargs):
  3. request_data = request.data
  4. pk = kwargs.get('pk')
  5. if pk:
  6. try:
  7. book_obj = models.Book.objects.get(pk=pk)
  8. print(pk)
  9. print(book_obj)
  10. except:
  11. return APIResponse.APIResponse(1,'update error')
  12. book_ser = Serializers.BookSerializer(instance=book_obj,data=request_data)
  13. book_ser.is_valid(raise_exception=True)
  14. res_obj = book_ser.save()
  15. return APIResponse.APIResponse(results=Serializers.BookSerializer(res_obj).data)
  16. elif isinstance(request_data,list) and len(request_data) !=0:
  17. obj_list = []
  18. data_list = []
  19. for dic in request_data:
  20. try:
  21. pk = dic.pop('pk')
  22. try:
  23. obj = models.Book.objects.filter(pk=pk).first()
  24. obj_list.append(obj)
  25. data_list.append(dic)
  26. except:
  27. pass
  28. except:
  29. return APIResponse.APIResponse(1,'update error')
  30. book_ser_list = Serializers.BookSerializer(instance=obj_list,data=data_list,many=True)
  31. book_ser_list.is_valid(raise_exception=True)
  32. book_res_list = book_ser_list.save()
  33. return APIResponse.APIResponse(results=Serializers.BookSerializer(book_res_list,many=True).data)
  34. else:
  35. return APIResponse.APIResponse(http_status=400,status=1,msg='update error')

10.(正常) 单局部改,序列化参数instance=修改的对象,data=修改的数据,partial=能否能局部修改,单整体改就是partial=False (默认就是False)

  1. # 单局部改 群局部改
  2. def patch(self, request, *args, **kwargs):
  3. request_data = request.data
  4. pk = kwargs.get('pk')
  5. if pk:
  6. try:
  7. book_obj = models.Book.objects.get(pk=pk)
  8. except:
  9. return APIResponse.APIResponse(1, 'update error')
  10. book_ser = Serializers.BookSerializer(instance=book_obj, data=request_data,partial=True)
  11. book_ser.is_valid(raise_exception=True)
  12. res_obj = book_ser.save()
  13. return APIResponse.APIResponse(results=Serializers.BookSerializer(res_obj).data)
  14. elif isinstance(request_data, list) and len(request_data) != 0:
  15. obj_list = []
  16. data_list = []
  17. for dic in request_data:
  18. try:
  19. pk = dic.pop('pk')
  20. try:
  21. obj = models.Book.objects.filter(pk=pk).first()
  22. obj_list.append(obj)
  23. data_list.append(dic)
  24. except:
  25. pass
  26. except:
  27. return APIResponse.APIResponse(1, 'update error')
  28. book_ser_list = Serializers.BookSerializer(instance=obj_list, data=data_list, many=True,partial=True)
  29. book_ser_list.is_valid(raise_exception=True)
  30. book_res_list = book_ser_list.save()
  31. return APIResponse.APIResponse(results=Serializers.BookSerializer(book_res_list, many=True).data)
  32. else:
  33. return APIResponse.APIResponse(http_status=400, status=1, msg='update error')

异常模块代码:


  1. from rest_framework.response import Response #导入Response类
  2. class APIResponse(Response): #继承Response类
  3. def __init__(self,status=0,msg='ok',results=None,http_status=None,headers=None,exception=None,**kwargs): #重写__init__方法
  4. data = {
  5. 'status':status,
  6. 'msg':msg
  7. }
  8. if results is not None:
  9. data['result'] = results
  10. data.update(**kwargs) #接收其他多余参数
  11. # 再使用父类的__init__方法
  12. super().__init__(data=data,status=http_status,headers=headers,exception=exception)

orm models代码:

  1. from django.db import models
  2. from django.conf import settings
  3. # 一、基表
  4. # Model类的内部配置Meta类要设置abstract=True,这样的Model类就是用来作为基表
  5. # 多表:Book,Publish,Author,AuthorDetail
  6. class BaseModel(models.Model):
  7. is_delete = models.BooleanField(default=False)
  8. create_time = models.DateTimeField(auto_now_add=True)
  9. class Meta:
  10. # 基表必须设置abstract,基表就是给普通Model类继承使用的,设置了abstract就不会完成数据库迁移完成建表
  11. abstract = True
  12. class Book(BaseModel):
  13. name = models.CharField(max_length=16)
  14. price = models.DecimalField(max_digits=5, decimal_places=2)
  15. publish = models.ForeignKey(to='Publish', related_name='books', db_constraint=False, on_delete=models.DO_NOTHING)
  16. # 重点:多对多外键实际在关系表中,ORM默认关系表中两个外键都是级联
  17. # ManyToManyField字段不提供设置on_delete,如果想设置关系表级联,只能手动定义关系表
  18. authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False)
  19. @property
  20. def author_detail(self):
  21. author_queryset = self.authors.all()
  22. author_detail = []
  23. for author_obj in author_queryset:
  24. author_detail.append(
  25. {
  26. 'name': author_obj.name,
  27. 'sex':author_obj.get_sex_display(),
  28. 'mobile':author_obj.detail.mobile
  29. }
  30. )
  31. return author_detail
  32. class Meta:
  33. verbose_name_plural = '书籍表'
  34. def __str__(self):
  35. return self.name
  36. class Publish(BaseModel):
  37. name = models.CharField(max_length=16)
  38. address = models.CharField(max_length=64)
  39. class Meta:
  40. verbose_name_plural = '出版社表'
  41. def __str__(self):
  42. return self.name
  43. class Author(BaseModel):
  44. name = models.CharField(max_length=16)
  45. sex = models.IntegerField(choices=[(0, '男'),(1, '女')], default=0)
  46. class Meta:
  47. verbose_name_plural='作者表'
  48. def __str__(self):
  49. return self.name
  50. class AuthorDetail(BaseModel):
  51. mobile = models.CharField(max_length=11)
  52. # 有作者可以没有详情,删除作者,详情一定会被级联删除
  53. # 外键字段为正向查询字段,related_name是反向查询字段
  54. author = models.OneToOneField(to='Author', related_name='detail', db_constraint=False, on_delete=models.CASCADE)

序列化代码:

  1. from rest_framework import serializers
  2. from rest_framework.serializers import ModelSerializer
  3. from . import models
  4. class BookListSerializer(serializers.ListSerializer):
  5. def update(self, instance, validated_data):
  6. return [
  7. self.child.update(instance[i],attrs) for i,attrs in validated_data
  8. ]
  9. class BookSerializer(ModelSerializer):
  10. class Meta:
  11. model = models.Book
  12. list_serializes_class = BookListSerializer
  13. fields = ['name','price','author_detail','publish','authors']
  14. extra_kwargs = {
  15. 'publish':{
  16. 'write_only':True
  17. },
  18. 'authors':{
  19. 'write_only':True
  20. }
  21. }
  22. class PublishSerilizer(ModelSerializer):
  23. books = BookSerializer(many=True)
  24. class Meta:
  25. model = models.Publish
  26. fields = ['name','address','books']

Django-rest Framework(五)的更多相关文章

  1. Django REST framework 五种增删改查方法

    Django-DRF-视图的演变   版本一(基于类视图APIView类) views.py: APIView是继承的Django View视图的. 1 from .serializers impor ...

  2. Django REST framework+Vue 打造生鲜超市(五)

    六.商品类别数据展示 6.1. 商品类别数据接口 (1)商品分类有两个接口: 一种是全部分类:一级二级三级 一种是某一类的分类以及商品详细信息: 开始写商品分类的接口 (2)序列化 给分类添加三级分类 ...

  3. Django Rest Framework源码剖析(五)-----解析器

    一.简介 解析器顾名思义就是对请求体进行解析.为什么要有解析器?原因很简单,当后台和前端进行交互的时候数据类型不一定都是表单数据或者json,当然也有其他类型的数据格式,比如xml,所以需要解析这类数 ...

  4. Django REST framework+Vue 打造生鲜超市(一)

    一.项目介绍 1.1.掌握的技术 Vue + Django Rest Framework 前后端分离技术 彻底玩转restful api 开发流程 Django Rest Framework 的功能实 ...

  5. Django REST framework+Vue 打造生鲜超市(三)

    四.xadmin后台管理 4.1.xadmin添加富文本插件 (1)xadmin/plugins文件夹下新建文件ueditor.py 代码如下: # xadmin/plugins/ueditor.py ...

  6. Django REST framework+Vue 打造生鲜超市(四)

    五.商品列表页 5.1.django的view实现商品列表页 (1)goods/view_base.py 在goods文件夹下面新建view_base.py,为了区分django和django res ...

  7. Django REST framework+Vue 打造生鲜超市(十二)

    十三.首页.商品数量.缓存和限速功能开发  13.1.轮播图接口实现 首先把pycharm环境改成本地的,vue中local_host也改成本地 (1)goods/serializer class B ...

  8. Django rest framework源码分析(1)----认证

    目录 Django rest framework(1)----认证 Django rest framework(2)----权限 Django rest framework(3)----节流 Djan ...

  9. 01 Django REST Framework 介绍

    01-Django REST Framework的介绍 Django REST框架是一个用于构建Web API的强大而灵活的工具包. 您可能希望使用REST框架的一些原因: 1. Web可浏览API对 ...

  10. Django Rest framework 框架

    一.开发模式: 1. 普通开发方式(前后端放在一起写) 2. 前后端分离(前后台通过ajaxo交互) 后端(django rest framework写的) <----ajaxo---> ...

随机推荐

  1. laravel装饰者模式例子

    interface Decorator{ public function display(); } class XiaoFang implements Decorator { private $nam ...

  2. USACO 2006 November Gold Corn Fields /// 状压 oj23941

    题目大意: 输入n m 接下来n行m列 0表示不能种玉米 1表示能 要求种玉米位置的上下左右四连通区域不能种玉米 输出方案数 Sample Input 2 31 1 10 1 0 Sample Out ...

  3. [记]Cordova安装插件选择插件版本

    在项目中可以使用 cordova plugin add [PLUGIN_ID] 這个命令安装一个cordova插件,这个命令好像是安装插件的最新版本.当需要通过cordova下载这个插件一个特定的版本 ...

  4. loj2513 治疗之雨

    题意:你的英雄一开始血量为p,你还有m个队友,血量无穷.血量上限为n,下限为0.如果血量满了就不能加血.每次启动操作,随机给m+1个英雄加1点血,然后等概率随机k次每次对于英雄扣1点血.求期望操作几次 ...

  5. leetcode-154-寻找旋转排序数组中的最小值

    题目描述: 方法一: class Solution: def findMin(self, nums: List[int]) -> int: left, right = 0, len(nums) ...

  6. [JZOJ3168] 【GDOI2013模拟3】踢足球

    题目 描述 题目大意 有两个队伍,每个队伍各nnn人. 接到球的某个人会再下一刻随机地传给自己人.敌人和射门,射门有概率会中. 每次射门之后球权在对方111号选手. 某个队伍到了RRR分,或者总时间到 ...

  7. Python3基础笔记_元组

    # Python3 元组 ''' Python 的元组与列表类似,不同之处在于元组的元素不能修改. 元组使用小括号,列表使用方括号. 元组中只包含一个元素时,需要在元素后面添加逗号,否则括号会被当作运 ...

  8. Lock方法是用于数据库的锁机制,

    Lock方法是用于数据库的锁机制,如果在查询或者执行操作的时候使用: lock(true); 复制代码   就会自动在生成的SQL语句最后加上 FOR UPDATE或者FOR UPDATE NOWAI ...

  9. 二分图——多重匹配模板hdu1669

    好像多重匹配一般是用网络流来做的.. 这是匈牙利算法的模板:lim是每个组的上界 思路是每个组都可以匹配lim个点,那么当点x遇到的组匹配的点数还没有超过lim时,直接匹配即可 如果已经等于了lim, ...

  10. Elasticsearch基本命令

    检查集群运行情况:    GET ->   localhost:9200/_cat/health?v 查看集群节点列表:    GET ->   localhost:9200/_cat?n ...