model.py
from django.db import models
# Create your models here.
from utils.base_model import BaseModel
class Projects(BaseModel):
name = models.CharField(max_length=20, verbose_name='项目名称', help_text='项目名称',
unique=True)
leader = models.CharField(max_length=10, verbose_name='项目负责人', help_text='项目负责人')
is_execute = models.BooleanField(verbose_name='是否启动项目', help_text='是否启动项目',
default=True)
desc = models.TextField(verbose_name='项目描述信息', help_text='项目描述信息',
null=True, blank=True, default='')
class Meta:
# i.db_table指定创建的数据表名称
db_table = 'tb_projects'
# 为当前数据表设置中文描述信息
verbose_name = '项目表'
verbose_name_plural = '项目表'
ordering = ['id']
def __str__(self):
return f"Projects({self.name})"
class Interfaces(BaseModel):
name = models.CharField(verbose_name='接口名称',help_text='接口名称',max_length=20,
unique=True)
tester = models.CharField(verbose_name='测试人员', help_text='测试人员', max_length=10)
projects = models.ForeignKey(Projects, on_delete=models.CASCADE,
verbose_name='所属项目', help_text='所属项目',related_name="interfaces")
class Meta:
# db_table指定创建的数据表名称
db_table = 'tb_interfaces'
# 为当前数据表设置中文描述信息
verbose_name = '接口表'
verbose_name_plural = '接口表'
ordering = ['id']
def __str__(self):
return f"{self.name}"
简单的定义方式
然后在serializers.py中定义序列化器,一般继承ModelSerializer
,快速生成 模型的序列化器。
额外的定义
- 如果转化的序列化器不符合要求,可以使用
extra_kwargs
进行局部修改- 如时间进行 格式化输出
- 修改某字段的各种校验不通过的提示语使用 error_messages
- 还可以使用自定义方法
- validate_字段名() ,单字段校验
- validate() , 多字段联合校验
反序列化时,代码校验执行顺序为:1 >>>>2 >>>> >3
如下:
from rest_framework import serializers
from rest_framework.validators import UniqueValidator
from .models import Projects,Interfaces
class InterfaceModelSerializer(serializers.ModelSerializer):
class Meta:
model = Interfaces
fields = "__all__"
extra_kwargs ={
"update_time": {
'format' : '%Y年%m月%d日 %H:%M:%S'
}
}
# 自定义方法
def is_contain_keyword(value):
if '李' not in value:
raise serializers.ValidationError('复制人必须姓李') # 必须是抛出这种异常
class ProjectsModelSerializer(serializers.ModelSerializer):
# 外键字段
# interfaces =serializers.PrimaryKeyRelatedField(many=True,read_only=True)
# interfaces = serializers.StringRelatedField(many=True,read_only=True) # 会用 __str__ 返回的字符串来展示
# interfaces = serializers.SlugRelatedField(many=True, read_only=True,slug_field="name") # 会用指定的某个字段(需是唯一的)来 展示
interfaces = InterfaceModelSerializer(many=True, read_only=True)
def validate_name(self, attr: str):
if not attr.endswith('项目'):
raise serializers.ValidationError("项目名称中,必须以“项目 结尾")
return attr
def validate(self,attrs):
attrs.get('leader')
attrs.get('name')
pass # 判断每个字段长度 等等
return attrs
class Meta:
model = Projects
fields = ["id","update_time","name","leader","is_execute","interfaces"] # '__all__'
extra_kwargs ={
"update_time": {'format' : '%Y年%m月%d日 %H:%M:%S'}, #【局部修改】 序列化输出时: 展示时间格式
"name":{'min_length':3,
'error_messages':{'max_length': '项目名称不能多余20位','min_length': '项目名称不能少于3位'}}, #【局部修改】 反序列化校验时,修改提示内容,补充定义某字段的最小长度等
# "leader":{"validators":[UniqueValidator(queryset=Projects.objects.all(),message="领导人要唯一,(默认为:该字段必须唯一。)")]} # 这个点在name中已经有这个了
# validataors 中还能用自定义方法:如下 (再运行过程中,会吧leader的值传个方法,从而进行校验)
"leader": {
"validators": [
# 方法1 方法不用打括号
# 方法2
is_contain_keyword
]}
}
补充
补充
: 还有两个和validate 同等级的方法(项目的案例?待补充),
- 反序列化校验时,单字段校验的入口方法
- 序列化输出的入口方法
校验的入口方法def to_internal_value(self, data):
def to_internal_value(self, data):
# to_internal_value方法,它是单字段 校验的入口方法
tmp =super().to_internal_value(data) # (这里就表示在执行单字段校验)
"""
# 这里可以增加 单字段校验结束之后的数据 进行修改的代码
print("单字段校验后, 联合字段校验前 可以做的事情") # tmp["name"]
"""
return tmp
输入的出口方法def to_representation
def to_representation(self, instance):
tmp =super(ProjectsModelSerializer, self).to_representation(instance)
"""
# 这里可以最后改造数据再进行返回
tmp["name"]="新名字"
"""
tmp["name"] = "新名字"
return tmp
补充2
create方法,和update方法、
serializer.save() 时,会调用这两个方法。
模型序列化器是自动带了这两个方法,实际上也是可以进行重写的
(比如save方法传了一些参数时:要重写,参考https://blog.csdn.net/Ataoker/article/details/131176006最侯一个菜单)
。
源码代码思维:django 中,把模型.objects.create() 的代码放到了序列化器中,好处是:抽离出 模型 的代码,不管哪种模型,只需要 serialize.save() ,就能完成创建 或者更新
可修改的方法
校验时:
0、单字段校验 def validate_name()
1、校验的入口方法:def to_internal_value(self, data) (单字段校验后,组合字段校验前的事情可以在这里做)
2、多字段联合校验方法 def validate()
修改输出
4、def create() 和 update() 方法
5、def to_representation(), 可以把响应改了
可以用这个方式的笔记,后面有空改
https://note.youdao.com/s/8L4wu3Z4 + https://note.youdao.com/s/RuzZJ0Mp