drf
序列化器使用时性能优化之根据请求类型动态变更serializer
及个性化序列化字段及 Django REST-FlexFields
使用
根据请求类型动态变更serializer
我们在drf
开发中我们遇到增删改查数据时,会遇到一些针对于增删改查的不同请求的json
请求, 我们可以使用不同的序列化器满足需求,闲话少说,直接上代码吧
- 首先我们定义相关的
models.py
中添加相关的模型
from django.db import models
class BookModels(models.Model):
id = models.BigAutoField("图书记录id号", primary_key=True)
Isbn_Card = models.CharField("图书isbn码", max_length=30, null=False, )
Book_Name = models.CharField("图书名称", max_length=100, null=False, blank=False)
Book_author = models.CharField("图书作者", max_length=100, null=False, blank=False)
Book_press = models.CharField("图书出版社", max_length=100, null=False, blank=False)
Book_stock = models.IntegerField("图书库存", default=0, null=False, blank=False)
Book_Creation_time = models.DateField("图书入库时间", auto_now_add=True, null=False, blank=False)
Book_notes = models.TextField("简介备用", null=False, blank=False)
Price = models.DecimalField("图书单价", max_digits=10000, decimal_places=2, null=False, blank=False, default=0)
class Meta:
verbose_name = "图书信息管理"
db_table = "BookInfo_Table"
verbose_name_plural = verbose_name
def __str__(self):
return f"{self.id}:{self.Isbn_Card}: {self.Book_Name}: {self.Book_author}:{self.Book_press}"
class BookAnother(models.Model):
name = models.CharField("name", max_length=12)
BookModel = models.ForeignKey(BookModels, on_delete=models.DO_NOTHING, verbose_name="图书信息管理", null=True)
class Meta:
verbose_name = "BookAnother"
db_table = "BookAnother_Table"
verbose_name_plural = verbose_name
- 其次在
Serializer.py
中新建相关的序列化器
# -*- coding: utf-8 -*-
# @Time : 2021/2/9 下午3:09
# @Author : void bug
# @FileName: Serializer.py
# @Software: PyCharm
from rest_framework import serializers
from apps.Book.models import *
class BookSerializers(serializers.ModelSerializer):
class Meta:
model = BookModels
fields = '__all__'
class BookAnotherUpDateSerializer(serializers.ModelSerializer):
class Meta:
model = BookAnother
fields = ("name",)
class BookAnotherSerializer(serializers.ModelSerializer):
class Meta:
model = BookAnother
fields = '__all__'
- 最后我们编写相关的
ViewSet.py
文件
# -*- coding: utf-8 -*-
# @Time : 2021/2/9 下午3:12
# @Author : void bug
# @FileName: ViewSet.py
# @Software: PyCharm
from rest_framework import viewsets
from apps.Book.Serializer import *
class BookViewSet(viewsets.ModelViewSet):
serializer_class = BookSerializers
queryset = BookModels.objects.all()
class BookAnotherViewSet(viewsets.ModelViewSet):
serializer_class = BookAnotherSerializer
queryset = BookAnother.objects.all()
def get_serializer_class(self):
# 根据请求类型动态变更serializer
if self.action == "update":
return BookAnotherUpDateSerializer
return BookAnotherSerializer
- 我们看下效果
个性化序列化字段
先在我们实现了根据请求类型动态变更serializer
,但是现在进行一些优化,但是我们为什么要进行优化呢,现在我们修改成功后只显示了 name 字段,但是我们修改成功后应该时都显示出来,故现在我们只需要修改BookAnotherViewSet.py
即可
class BookAnotherUpDateSerializer(serializers.ModelSerializer):
name = serializers.CharField(max_length=12, read_only=True)
class Meta:
model = BookAnother
fields = '__all__'
- 我们看下效果
Django REST-FlexFields
使用
好的我们已经实现了上述的功能了,但是我们现在项显示相关的外键的信息,现在我们需要导入一个外键的包Django REST-FlexFields
- Django REST Framework序列化程序的灵活,动态字段和嵌套模型。
- 总览
用于Django REST Framework的FlexFields(DRF-FF)是一个软件包,旨在为在DRF序列化程序中动态设置字段和嵌套模型提供功能的通用基准。该软件包的设计旨在简化,与DRF的基础类的纠缠最少。
主要优点:- 通过查询参数(
users/?expand=organization,friends
)轻松设置可扩展为完全序列化的字段 - 通过以下任一方法选择字段的子集:
- 指定应包含哪些(
users/?fields=id,first_name
) - 指定应排除的项目(
users/?omit=id,first_name
)
- 指定应包含哪些(
- 使用点表示法可动态修改任意深度的字段(
users/?expand=organization.owner.roles
) - 灵活的API-选项也可以直接传递给序列化器:
UserSerializer(obj, expand=['organization'])
- 通过查询参数(
安装
pip install drf-flex-fields
配置序列化器
然后让您的序列化器子类FlexFieldsModelSerializer
:
# -*- coding: utf-8 -*-
# @Time : 2021/2/9 下午3:09
# @Author : void bug
# @FileName: Serializer.py
# @Software: PyCharm
from rest_flex_fields import FlexFieldsModelSerializer
from rest_framework import serializers
from apps.Book.models import *
class BookSerializers(serializers.ModelSerializer):
class Meta:
model = BookModels
fields = '__all__'
class BookAnotherUpDateSerializer(FlexFieldsModelSerializer):
name = serializers.CharField(max_length=12, read_only=True)
class Meta:
model = BookAnother
fields = '__all__'
expandable_fields = {
"BookModel": BookSerializers
}
class BookAnotherSerializer(FlexFieldsModelSerializer):
class Meta:
model = BookAnother
fields = '__all__'
expandable_fields = {
"BookModel": BookSerializers
}
其他的不用修改
运行结果
http://127.0.0.1:8000/api/BookAnother/1/
http://127.0.0.1:8000/api/BookAnother/1/?expand=BookModel
安全优化
我们现在修改一下
# -*- coding: utf-8 -*-
# @Time : 2021/2/9 下午3:09
# @Author : void bug
# @FileName: Serializer.py
# @Software: PyCharm
from rest_flex_fields import FlexFieldsModelSerializer
from rest_framework import serializers
from apps.Book.models import *
class BookSerializers(serializers.ModelSerializer):
class Meta:
model = BookModels
fields = '__all__'
class BookReadOnlySerializer(serializers.ModelSerializer):
Isbn_Card = serializers.CharField(read_only=True)
Book_Name = serializers.CharField(read_only=True)
Book_author = serializers.CharField(read_only=True)
Book_press = serializers.CharField(read_only=True)
Book_stock = serializers.IntegerField(read_only=True)
Book_notes = serializers.CharField(read_only=True)
Price = serializers.DecimalField(read_only=True, max_digits=10000, decimal_places=2)
class Meta:
model = BookModels
fields = '__all__'
class BookAnotherUpDateSerializer(FlexFieldsModelSerializer):
name = serializers.CharField(max_length=12, read_only=True)
class Meta:
model = BookAnother
fields = '__all__'
expandable_fields = {
"BookModel": BookReadOnlySerializer
}
class BookAnotherSerializer(FlexFieldsModelSerializer):
class Meta:
model = BookAnother
fields = '__all__'
expandable_fields = {
"BookModel": BookSerializers
}
运行结果