使用tortoise-orm,通过Pydantic序列化查询集,除了模型自带的字段,用户如果想自己自定义一些跟模型字段有管的字段,就可以通过computed来添加到Pydantc。
下面通过用户-徽章和用户徽章中间表关系来举例
class Badge(models.Model):
"""徽章表"""
id = fields.IntField(pk=True)
name = fields.CharField(max_length=32, verbose_name="徽章名")
score = fields.FloatField(default=100, help_text="获得徽章时增加的积分", verbose_name='增加积分')
buff = fields.FloatField(default=1.5, help_text="徽章效果, 即获得积分增益倍数", verbose_name='增益倍数')
image = fields.TextField(default="", blank=True, verbose_name='图片')
image_gray = fields.TextField(default="", blank=True, verbose_name="灰色图")
image_light = fields.TextField(default="", blank=True, verbose_name='光效图')
class UserBadge(models.Model):
"""用户徽章表"""
id = fields.IntField(pk=True)
user: fields.ForeignKeyRelation[User] = fields.ForeignKeyField("cp_model.User", on_delete=fields.CASCADE,
related_name="user_badges")
badge: fields.ForeignKeyRelation[Badge] = fields.ForeignKeyField("cp_model.Badge",
on_delete=fields.CASCADE)
expired = fields.DatetimeField(default=default_expired_time, help_text="徽章buff的过期时间", blank=True)
class Meta:
unique_together = (("user", "badge"),) # 进行手动判断
ordering = ("expired",)
table = "cp_user_badge"
class User(models.Model):
"""用户表"""
id = fields.IntField(pk=True)
wx_uid = fields.CharField(max_length=32)
open_id = fields.CharField(max_length=32, default="", null=True, blank=True)
name = fields.CharField(max_length=32, index=True)
def valid_badges(self) -> list:
# return []
if not self.user_badges.related_objects:
return []
return [_ for _ in self.user_badges if _.expired >= timezone.now()]
class PydanticMeta:
computed = ["valid_badges"]
想要获取用户信息以及用户的徽章列表信息,徽章获取时想要筛选没过期的徽章列表。
如下:在model里User表中通过关联关系名user_badges来获取关系,需要在Pydantic中声明user_badges,需要添加一个valid_badges字段,就需要再model里面函数形式声明字段名,并使用computed 字段來指明。
class OnlyOneUserSchema(
pydantic_model_creator(
User, name="OnlyOneUserSchema",
exclude=())
):
"""用户详情"""
user_badges: List[UserBadgeSimpleSchema] = None
valid_badges: List[UserBadgeSimpleSchema] = None