考虑以下模型:
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'
我在这里想念什么?
答案 0 :(得分:0)
您应该将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)()