首页 > 解决方案 > django 将昂贵的计算缓存到数据库中

问题描述

所以我有这样的模型。

class User(CoreModel, AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(
        unique=True,
        verbose_name=_('email'),
        help_text=_("user's email address"),
        max_length=255
    )
    username = models.CharField(
        verbose_name=_('username'),
        help_text=_("display name"),
        unique=True,
        db_index=True,
        max_length=32,
        validators=(
            MinLengthValidator(2),
            UnicodeUsernameValidator
        )
    )
    avatar = models.ImageField(
        verbose_name=_('avatar'),
        help_text=_("user avatar"),
        upload_to='avatars/',
        default='avatars/default.jpg',
    )
    is_verified = models.BooleanField(
        default=False,
        verbose_name=_('verified'),
        help_text=_("whether the user's email is verified")
    )
    @property
    def space_used(self):
        output_field = models.DecimalField()
        aggregate = self.upload_set.aggregate(
            space=Coalesce(
                models.Sum('size'),
                models.Value(0),
                output_field=output_field
            ),
        )
        return aggregate.get('space')


class Upload(CoreModel):
    size = models.DecimalField(
        editable=False,
        verbose_name=_('size'),
        help_text=_("size in bytes"),
        max_digits=19,
        decimal_places=10,
        db_index=True
    )
    name = models.CharField(
        blank=True,
        verbose_name=_('name'),
        help_text=_("upload name"),
        max_length=100,
        validators=(
            MinLengthValidator(2),
        )
    )
    parent = models.ForeignKey(
        to='uploads.Folder',
        verbose_name=_('folder'),
        on_delete=models.CASCADE,
        null=True,
        db_index=True
    )
    owner = models.ForeignKey(
        to=settings.AUTH_USER_MODEL,
        verbose_name=_('owner'),
        on_delete=models.CASCADE,
        editable=False
    )
    file = models.FileField(
        verbose_name=_('file'),
        help_text=_("raw file"),
        upload_to='uploads/'
    )

如您所见, space_used 属性是一项昂贵的操作。如果每个用户的上传数量增加,则将花费更多时间进行计算。实际上,我通过我的序列化程序经常使用这个属性。那么,提高性能的更好方法是什么?

space_used每当创建或删除上传时,是否调用了一个 db 字段并对其进行更新?还是有其他更好的实现方式?我不想使用 cached_property 因为实例不会在请求之间持续存在。

请告诉我!多谢!

标签: djangodjango-modelsdjango-caching

解决方案


推荐阅读