return queryset with annotate 的 django 模型方法

django model method to return queryset with annotate

我正在尝试定义一个基于 user_type 计算的字段,我做了以下方法但它不起作用,如果有人可以建议我正确的方法。

所以我想在这里实现的是构造一个方法,例如 <user>.book_limit 到 return 基于 user_type

的最大允许书籍数量
#models.py 

class UserProfile(models.Model):
    class UserType(models.TextChoices):
        FREE = 'FR', 'FREE'
        BASIC = 'BS', 'BASIC'
        PREMIUM = 'PR', 'PREMIUM'

    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    bio = models.CharField(max_length=255)
    created_on = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)
    user_type = models.CharField(max_length=2, choices=UserType.choices, default=UserType.FREE)

    def __str__(self):
        return self.user.username

    @property
    def borrow_limit(self):
        return UserProfile.objects.annotate(book_limit=Case(
            When(user_type=UserProfile.UserType.FREE, then=Value('1')),
            When(user_type=UserProfile.UserType.BASIC, then=Value('2')),
            When(user_type=UserProfile.UserType.PREMIUM, then=Value('5')),
            default=Value('1'), output_field=IntegerField))

您可以像 here 中描述的那样自定义您的初始查询集。

您可以使用管理器来每次注释值:

from django.db.models import Case, IntegerField, Value, When

class <b>UserProfileManager</b>(models.Manager):

    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).annotate(
            book_limit=Case(
                When(user_type=UserProfile.UserType.FREE, then=Value(1)),
                When(user_type=UserProfile.UserType.BASIC, then=Value(2)),
                When(user_type=UserProfile.UserType.PREMIUM, then=Value(5)),
                default=Value(1),
                output_field=IntegerField()
            )
        )

class UserProfile(models.Model):
    class UserType(models.TextChoices):
        FREE = 'FR', 'FREE'
        BASIC = 'BS', 'BASIC'
        PREMIUM = 'PR', 'PREMIUM'

    user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile')
    bio = models.CharField(max_length=255)
    created_on = models.DateTimeField(auto_now_add=True)
    last_updated = models.DateTimeField(auto_now=True)
    user_type = models.CharField(max_length=2, choices=UserType.choices, default=UserType.FREE)
    objects = <b>UserProfileManager()</b>