computed自定义添加Pydantic序列化字段

使用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

tip:要想从关联关系表进行条件筛选,可以通过Prefetch来实现

你可能感兴趣的:(computed自定义添加Pydantic序列化字段)