python - 如何在 Django 中向查询集添加自定义属性?

标签 python django django-models

考虑以下模型:

class User(AbstractUser):
    def messages(self):
        return Message.objects.filter(user=self).order_by('-created_on')

class Message(models.Model):
    user = models.ForeignKey('account.User', related_name='message', on_delete=models.CASCADE)
    created_on = models.DateTimeField(auto_now=True)
    data = models.TextField()
    read = models.BooleanField(default=False)

    objects = MessageManager()

我想重写 Message 模型的 QuerySet 行为以包含自定义方法 unread_count:

class MessageManager(models.Manager):
    def get_queryset(self):
        queryset = super().get_queryset()
        unread_count = queryset.filter(read=False).count()
        print(unread_count) # this works

        # these don't work
        queryset.unread_count = unread_count
        setattr(queryset, 'unread_count', unread_count)
        #

        return queryset

messages 方法工作正常,并且管理器内的 print 语句执行,但如果我尝试访问 unread_count,我会收到 AttributeError:

>>>user = User.objects.get(id=1)
>>>messages = user.messages()
2 # this is from the print statement
>>>messages.unread_count
AttributeError: 'QuerySet' object has no attribute 'unread_count'

我在这里缺少什么?

最佳答案

您应该对 models.QuerySet 进行子类化,而不是 models.Manager :

class MessageQuerySet(models.QuerySet):
    @property
    def unread_count(self):
        return self.filter(read=False).count()

然后使用as_manager模型中的方法:

class Message(models.Model):
    ...

    objects = MessageQuerySet.as_manager()

如果您需要向从管理器返回的 QuerySet 以及管理器本身添加方法,则需要使用 from_queryset :

class MessageManager(models.Manager):
    def some_manager_only_method(self):
        print('do stuff')

class MessageQuerySet(models.QuerySet):
    @property
    def unread_count(self):
        return self.filter(read=False).count()

class Message(models.Model):
    ...

    objects = MessageManager.from_queryset(MessageQuerySet)()

关于python - 如何在 Django 中向查询集添加自定义属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58210689/

相关文章:

python - 匿名用户错误

django - 如何使用 ssl 和域在 aws 中部署 react 和 django

python - Django:unique_together 是否以与 ForeignKey 相同的方式暗示 db_index=True?

django - 从 django admin 中的 URL 预填充 DateTimeField

python - path = path + [node1], path += [node1] 和 path.append(node1) 的区别

python - Flask Webapp - 注册后验证电子邮件 - 最佳实践

Python webbrowser.open() 打开 Chrome 浏览器

django - 如何使用 Django 的模板扩展变量?

python - 如何在python中找到直方图的包络线(连续函数)

python - 在多对多字段中使用 through 属性并遇到 "Non-Unique"字段要求