关键词:
一、Response二次封装
我们想要对响应类进行自定义,以后就用我们自己自定义的响应类
# 新建response.py文件 from rest_framework.response import Response class APIResponse(Response): def __init__(self, status=0, msg=‘ok‘, http_status=None, headers=None, exception=False, **kwargs): # 将外界传入的数据状态码、状态信息以及其他所有额外存储在kwargs中的信息,都格式化成data数据 data = ‘status‘: status, ‘msg‘: msg # 在外界数据可以用result和results来存储 if kwargs: data.update(kwargs) super().__init__(data=data, status=http_status, headers=headers, exception=exception) # 使用: # APIResponse() 代表就返回 "status": 0, "msg": "ok" # APIResponse(result="结果") 代表返回 "status": 0, "msg": "ok", "result": "结果" # APIResponse(status=1, msg=‘error‘, http_status=400, exception=True) 异常返回 "status": 1, "msg": "error"
二、数据库关系
1、断连分析
""" 1)之间有关系的两个表,增删改操作会相互影响(效率低),查询操作就是正常的连表操作 2)之间有关系的两个表,断开关联,但所有数据保持与原来一致 每个表都可以单独操作,增删改操作效率极高,但是容易出现脏数据(开发中完全可以避免) 由于数据没有任何变化,所以查询的连表操作不会受到任何影响 3)Django的ORM支持断关联操作关系表,且所有的操作方式和没有断关联操作一致 """
2、orm操作关系
""" 外键位置: 1)一对多:ForeignKey必须放在多的一方,书与出版社,外键应该放在书表 2)多对多:ManyToManyField放在任何一方都可以,因为会创建关系表,在关系表中用两个外键分别关联两个表 3)一对一:OneToOneField放在依赖的表,作者与作者详情,放在详情表,OneToOneField会被转换为 外键 + 唯一约束 """ """ ORM关系Field: ForeignKey可以设置related_name, db_constraint, on_delete OneToOneField可以设置related_name, db_constraint, on_delete ManyToManyField只能设置related_name, db_constraint 不能设置on_delete的原因:不管是关联的A表,还是B表,数据修改,都会影响到关系表(默认级联), 如果想控制,只能自定义关系表,在关系表的两个外键分别设置on_delete """ """ 参数含义 related_name:表之间反向访问的名字,默认是 表名小写|表名小写_set db_constraint:表之间的关联关系,默认为True,代表关联,设置False,可以提高增删改的效率,且不影响查等其他操作 on_delete:在django 1.x下默认是CASCADE,在django 2.x下必须手动明确 """ """ 表关系: 作者没,作者详情一定没:CASCADE ***** 作者没,书还是该作者出的:DO_NOTHING 部门没,部门内的员工全部进入未分组部门:SET_DEFAULT (需要配合default属性使用) 部门没,部门内的员工部门外键字段设置为空:SET_NULL (需要配合null=True属性使用) ***** """
3、案列
class Author(models.Model): name = models.CharField(max_length=64) class AuthorDetail(models.Model): phone = models.CharField(max_length=11) # related_name就是可以方向访问,比如主键在作者详情,作者访问作者详情就可以直接.detail就相当于来到了详情表 # db_constraint是控制两张表之间是否有关联,默认是True,改为False就是断关联 author = models.OneToOneField(to=Author, related_name=‘detail‘, db_constraint=False, # on_delete=models.CASCADE # on_delete=models.DO_NOTHING # default=1 on_delete=models.SET_NULL, null=True )
测试
import os, django # 导入环境 os.environ.setdefault("DJANGO_SETTINGS_MODULE", "d_proj.settings") # 加载配置文件 django.setup() # 启动 from api.models import Author, AuthorDetail # 测试正向反向查询 # a1 = Author.objects.first() # print(a1.name) # print(a1.detail.phone) # ad2 = AuthorDetail.objects.last() # print(ad2.phone) # print(ad2.author.name) # 级联关系测试 # django1.x版本默认的就是级联删除,级联更新,所以我们把作者删除了,那在作者详情中关联作者的那个字段也会被删除 # ad2 = AuthorDetail.objects.last() # type: AuthorDetail # ad2.delete() # Author.objects.first().delete()
三、基表
# 基类:是抽象的(不会完成数据库迁移),目的是提供一些共有的字段 class BaseModelk(models.Model): is_delete = models.BooleanField(default=False) updated_time = models.DateTimeField(auto_now_add=True) class Meta: abstract = True # 注意:必须完成该配置才可以让别的类去继承基类
应用
class Book(BaseModel): name = models.CharField(max_length=64) price = models.DecimalField(max_digits=5, decimal_places=2, null=True) image = models.ImageField(upload_to=‘img‘, default=‘img/default.png‘) publish = models.ForeignKey(to=‘Publish‘, related_name=‘books‘, db_constraint=False, on_delete=models.DO_NOTHING) authors = models.ManyToManyField(to=‘Author‘, related_name=‘books‘, db_constraint=False) class Publish(BaseModel): name = models.CharField(max_length=64) class Author(BaseModel): name = models.CharField(max_length=64) class AuthorDetail(BaseModel): phone = models.CharField(max_length=11) author = models.OneToOneField( to=Author, related_name=‘detail‘, db_constraint=False, on_delete=models.SET_NULL, null=True )
四、序列化的其他配置(了解)
1、补充
class AuthorModelSerializer(serializers.ModelSerializer): class Meta: model = models.Author # 不常用,将全部字段提供给外界 fields = ‘__all__‘ # ------------------------------------------------------------------ class AuthorModelSerializer(serializers.ModelSerializer): class Meta: model = models.Author # 不常用,排除指定字段的其他所有字段,不能自动包含 外键反向 字段 exclude = [‘is_delete‘, ‘updated_time‘] # ------------------------------------------------------------------ class AuthorModelSerializer(serializers.ModelSerializer): class Meta: model = models.Author # ‘detail‘, ‘books‘ 是 外键(正向|反向) 字段 fields = [‘name‘, ‘detail‘, ‘books‘] # 不常用,自动深度,自动深度会显示外键关联表的所有字段 depth = 2 # 正向外键字段:就是外键的属性名 # 反向外键字段:就是外键属性设置的related_name
2、子序列化
""" 1)子序列化的字段,必须是 外键(正向|反向) 字段 2)子序列化 一定有上下关系.:子序列化类必须写在上方,且只能对外键(正向反向)字段进行覆盖,一般只有查需求的资源,可以采用子序列化 3)子序列化对应的数据是单个many=False,数据对应是多个many=True 4)子序列化其实就是自定义序列化字段,覆盖了原有 外键(正向|反向)字段 的规则,所以不能进行反序列化 """
3、案列
子路由urls.py
url(r‘^authors/$‘, views.AuthorAPIView.as_view()), url(r‘^authors/(?P<pk>d+)/$‘, views.AuthorAPIView.as_view()),
serializers.py
from rest_framework import serializers from . import models class AuthorDetailModelSerializer(serializers.ModelSerializer): class Meta: model = models.AuthorDetail fields = [‘phone‘] class BookModelSerializer(serializers.ModelSerializer): class Meta: model = models.Book fields = [‘name‘, ‘price‘] class AuthorModelSerializer(serializers.ModelSerializer): # 子序列化:子序列化类必须写在上方,且只能对 外键(正向反向)字段 进行覆盖 # 注:运用了子序列化的外键字段,就不能进行数据库的反序列化过程 detail = AuthorDetailModelSerializer(many=False, read_only=True) books = BookModelSerializer(many=True, read_only=True) # 问题: # 1)不设置read_only时,就相当于允许反序列化,反序列化时就会报错 # 2)设置read_only时,可以完成反序列化,但是新增的数据再序列化了,就没有外键关联的数据,与原来数据格式就不一致了 class Meta: model = models.Author fields = [‘name‘, ‘detail‘, ‘books‘]
views.py
# 实际开发,资源的大量操作都是查询操作,只有查需求的资源,可以采用子序列化 class AuthorAPIView(APIView): def get(self, request, *args, **kwargs): pk = kwargs.get(‘pk‘) if pk: obj = models.Author.objects.filter(is_delete=False, pk=pk).first() serializer = serializers.AuthorModelSerializer(instance=obj) return APIResponse(result=serializer.data) else: queryset = models.Author.objects.filter(is_delete=False).all() serializer = serializers.AuthorModelSerializer(instance=queryset, many=True) return APIResponse(results=serializer.data) # 测试子序列化外键字段,不能参与反序列化 def post(self, request, *args, **kwargs): serializer = serializers.AuthorModelSerializer(data=request.data) if serializer.is_valid(): obj = serializer.save() return APIResponse(result=serializers.AuthorModelSerializer(instance=obj).data, http_status=201) else: # 校验失败 => 异常响应 return APIResponse(1, serializer.errors, http_status=400)
五、多表序列化与反序列化
""" 1)外键字段要参与反序列化,所以外键字段设置为write_only 2)外键关系需要连表序列化结果给前台,可以用@property来自定义连表序列化 """
案例
urls.py
url(r‘^books/$‘, views.BookAPIView.as_view()), url(r‘^books/(?P<pk>d+)/$‘, views.BookAPIView.as_view()),
models.py
class Book(BaseModel): name = models.CharField(max_length=64) price = models.DecimalField(max_digits=5, decimal_places=2, null=True) image = models.ImageField(upload_to=‘img‘, default=‘img/default.png‘) publish = models.ForeignKey(to=‘Publish‘, related_name=‘books‘, db_constraint=False, on_delete=models.DO_NOTHING) authors = models.ManyToManyField(to=‘Author‘, related_name=‘books‘, db_constraint=False) @property # @property字段默认就是read_only,且不允许修改 def publish_name(self): return self.publish.name @property # 自定义序列化过程 def author_list(self): temp_author_list = [] for author in self.authors.all(): author_dic = "name": author.name try: author_dic[‘phone‘] = author.detail.phone except: author_dic[‘phone‘] = ‘‘ temp_author_list.append(author_dic) return temp_author_list @property # 借助序列化类完成序列化过程 def read_author_list(self): from .serializers import AuthorModelSerializer return AuthorModelSerializer(self.authors.all(), many=True).data class Publish(BaseModel): name = models.CharField(max_length=64) class Author(BaseModel): name = models.CharField(max_length=64) class AuthorDetail(BaseModel): phone = models.CharField(max_length=11) author = models.OneToOneField( to=Author, related_name=‘detail‘, db_constraint=False, on_delete=models.SET_NULL, null=True )
serializers.py
# 辅助序列化格式化的类 class AuthorDetailModelSerializer(serializers.ModelSerializer): class Meta: model = models.AuthorDetail fields = [‘phone‘] # 辅助序列化格式化的类 class AuthorModelSerializer(serializers.ModelSerializer): # 使用了子序列化 detail = AuthorDetailModelSerializer(many=False, read_only=True) # 一对一关系 class Meta: model = models.Author fields = [‘name‘, ‘detail‘] # 主序列化类 class BookModelSerializer(serializers.ModelSerializer): class Meta: model = models.Book # fields = [‘name‘, ‘price‘, ‘image‘, ‘publish‘, ‘authors‘, ‘publish_name‘, ‘author_list‘, ‘read_author_list‘] fields = [‘name‘, ‘price‘, ‘image‘, ‘publish‘, ‘authors‘] extra_kwargs = ‘image‘: ‘read_only‘: True, , ‘publish‘: # 系统原有的外键字段要留给反序列化过程使用,序列化外键内容用@property自定义 ‘write_only‘: True, , ‘authors‘: ‘write_only‘: True, ,
views.py
# 六个必备接口:单查,群查,单增,单删,单整体改(了解),单局部改 # 四个额外接口:群增,群删,群整体改,群局部改 class BOOKAPIView(APIView): # 序列化 # 单查群查 def get(self, request, *args, **kwargs): pk = kwargs.get(‘pk‘) if pk: obj = models.Book.objects.filter(is_delete=False, pk=pk).first() serializer = serializers.BookModelSerializer(instance=obj) return APIResponse(result=serializer.data) else: queryset = models.Book.objects.filter(is_delete=False).all() serializer = serializers.BookModelSerializer(instance=queryset, many=True) return APIResponse(results=serializer.data) # 反序列化 # 单增群增 def post(self, request, *args, **kwargs): # 如何区别单增群增:request.data是还是[] if not isinstance(request.data, list): # isinstance()是用来判断一个对象是否是某个类型 # 单增 serializer = serializers.BookModelSerializer(data=request.data) serializer.is_valid(raise_exception=True) # 如果校验失败会直接抛异常返回给前台 obj = serializer.save() # 为什么要将新增的对象重新序列化给前台,因为序列化与反序列化数据不对等 return APIResponse(result=serializers.BookModelSerializer(obj).data, http_status=201) else: # 群增 serializer = serializers.BookModelSerializer(data=request.data, many=True) serializer.is_valid(raise_exception=True) # 如果校验失败会直接抛异常返回给前台 objs = serializer.save() # 为什么要将新增的对象重新序列化给前台,因为序列化与反序列化数据不对等 return APIResponse(result=serializers.BookModelSerializer(objs, many=True).data, http_status=201)
# 友情注释:群增其实是借助了ListSerializer来的create方法完成的
六、小结
""" 1)二次封装Response: 自定义类继承Response,重写init方法,在内部格式化data 2)表关系分析: 断关联: 优点:提示增删改操作效率,不允许查效率 缺点:增删改操作可能会导致脏数据,所以需要通过逻辑或是事务来保证 3)ORM表关系处理语法: 1)外键所在位置 2)如何断关联db_constraint 3)正向方向自定义名字:related_name 4)表关系:on_delete四种 4)基表:Meta中配置abstract=True,来被继承,提供共有字段 5)多表连表Meta中的了解配置 fields = ‘__all__‘ # 不常用,将全部字段提供给外键 exclude = [‘is_delete‘, ‘updated_time‘] # 不常用,排除指定字段的其他所有字段 depth = 2 # 不常用,主动深度,自动深度会显示关联表的所有字段 6)子序列化 i)通常只用于序列化过程,对外键字段进行了覆盖,影响外键字段的反序列化过程 class SubSerializer: pass class SupSerializer: 外键 = SubSerializer(many=True|False) 7)多表的序列化与反序列化 1)连表序列化用自定义@property完成:内部实现可以自定义逻辑,也可以走序列化类 2)外键字段留给反序列化来使用 8)单查、群查、单增、群增接口 """
djangorestframework---序列化组件(代码片段)
一、序列化组件的作用 在前后端分离开发时,前端与后端用来交互的数据的格式是一致的(数据格式为字符串的json数据),于是后端程序员在传递数据时,便要将数据封装成符合格式的数据,如果不借助方法,手动进行数... 查看详情
djangorestframework序列化组件总结(代码片段)
序列化组件总结一.序列化组件本质上为了实现前后端分离,而进行json序列化的一个组件形式,极大方便了解析数据的作用二.所有序列化是基于APIView解析器实现的,通过内部的多继承关系方便实现进行数据序列化的实现三使用方式1.... 查看详情
django框架(十九)——序列化组件(serializer)(代码片段)
目录序列化组件一、利用for循环来实现序列化(繁琐)二、利用Django提供的序列化组件(不可控需要的字段)三、利用drf提供的序列化组件1、基于Serializer类实现序列化——基本语法2、基于Serializer类实现序列化——高级语法3、... 查看详情
django-组件拾遗(代码片段)
...ngo的modelform组件三Django的缓存机制四Django的信号五Django的序列化一Django的form组件forms组件二Django的modelform组件这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,先来一个简单的例子来看... 查看详情
django组件拾忆(代码片段)
...ngo的modelform组件三Django的缓存机制四Django的信号五Django的序列化回到顶部一Django的form组件回到顶部二Django的modelform组件这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来回到顶部三Django... 查看详情
django-缓存机制,form组件(代码片段)
...ngo的modelform组件三Django的缓存机制四Django的信号五Django的序列化回到顶部一Django的form组件回到顶部二Django的modelform组件这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来回到顶部三Django... 查看详情
drf框架(代码片段)
...析模块、渲染模块、响应模块、异常模块四、drf核心组件序列化组件:将后台的任何数据,进行序列化返回给前台;将前台的数据反序列化成后台model对象再入库三大认证组件:认证组件、权限组件(RBAC)、频率组件视图家族:View... 查看详情
drf序列化(代码片段)
一、安装Django RESTframework框架使用命令:pipinstalldjangorestframework二、在setings里面注册INSTALLED_APPS=["rest_framework"]Serializers序列化组件 查看详情
modelserializer组件(代码片段)
ModelSerializer组件一、DRF模型类序列化器如果我们想要使用序列化器对应的是Django的模型类,DRF为我们提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类。ModelSerializer与常规的Serializer相同,但提供了:基于模型... 查看详情
drf序列化大总结(代码片段)
目录一、APIView的请求生命周期二、序列化组件视图类中使用序列化Meta配置类中的配置自定义校验规则入库方法自定义字段如果有群改操作重(难)点三、视图家族四、路由组件五、权限认证一、APIView的请求生命周期'''1)... 查看详情
$django序列化组件(代码片段)
1序列化组件fromapp01importmodelsfromrest_frameworkimportserializersfromrest_framework.serializersimportSerializer,ModelSerializerfromdjango.httpimportJsonResponseclassauth(Serializer):name=serializers.Char 查看详情
序列化组件(代码片段)
序列化组件把后端的数据对象序列化成json格式的字符串传到前端一 Django内置的serializers(把对象序列化成json字符串)fromdjango.coreimportserializersfromdjango.coreimportserializersdeftest(request):book_list=Book.objects.all()ret=seriali 查看详情
restfull02序列化组件(代码片段)
RESTFULLL序列化组件一、Django自带序列化组件?内置的serializers(把对象序列化成json字符串)(一般不用)fromdjango.coreimportserializersdeftest(request):book_list=Book.objects.all()ret=serializers.serialize("json",book_list)retu 查看详情
序列化组件(代码片段)
序列化组件使用depth获取跨表数据当有表有外键存在时,在序列化组件时简单的获取关联表的数据方法classCourseSerializers(ModelSerializer):classMeta:model=Coursefields=‘__all__‘depth=1#建议0-10当为0时,无作用,当为1时,可以获取外键关联的... 查看详情
视图组件代码(代码片段)
序列化器代码#声明序列化器fromrest_frameworkimportserializersfromdjangoDome.modelsimportBookclassPublisherSerializer(serializers.Serializer):id=serializers.IntegerField()title=serializers.CharField(max_length=32)c 查看详情
序列化组件的使用(代码片段)
序列化组件的使用序列化器的作用:序列化:序列化器会将模型对象转换成字典,经过response变成json格式字符串反序列化:把客户端发来的数据,经由response对象变成字典,序列化器可以将字典转换成模型对象反序列化,可以完成... 查看详情
djangorestframework之序列化组件(代码片段)
一.serializersfromrest_framework.viewsimportAPIViewfromapp01importmodelsfromrest_framework.responseimportResponsefromrest_frameworkimportserializers#使用serializers需要先定义一个类,类里面的内容要和models一致classBookSeria 查看详情
drf序列化组件(代码片段)
modelsfromdjango.dbimportmodels#Createyourmodelshere.classBook(models.Model):nid=models.AutoField(primary_key=True)name=models.CharField(max_length=32)price=models.DecimalField(max_digits=5,decimal_pl 查看详情