django - Django:有条件地覆盖get_queryset
问题描述
姜戈 1.11
我有两个模型。我想有条件地覆盖他们经理的默认行为。
class Project(models.Model):
title = models.CharField(max_length=50)
class Task(models.Model):
title = models.CharField(max_length=50)
project = models.ForeignKey(Project,
null=True,
blank=True,
related_name='tasks')
protected = models.BooleanField(default=False)
objects = TaskManager()
class TaskManager(models.Manager):
def get_queryset(self):
return super(TaskManager, self).get_queryset().exclude(protected=True)
应该从任何未明确要求它们的查询中过滤的任务protected = True
(我知道 Django 文档建议不要过滤覆盖的get_queryset()
)
使用上面的代码,任何查询project.tasks
都会返回所有相关的任务 where protected = False
,正如预期的那样。
如何有条件地覆盖get_queryset()
以仅返回相关任务 where protected = True
?像:project.protected_tasks
或project.tasks.protected
?
解决方案
这是我想出的一个解决方案——这个想法是朝着另一个方向发展。我相信有更优雅的方法可以做到这一点。
class Project():
def protected_tasks(self):
return Task.protected_tasks.filter(project=self.id)
class ProtectedTaskManager():
def get_queryset(self):
return super(ProtectedTaskManager, self).get_queryset().filter(protected=True)
class TaskManager():
def get_queryset(self):
return super(TaskManager, self).get_queryset().exclude(protected=True)
class Task():
objects = TaskManager()
protected_tasks = ProtectedTaskManager()
project.tasks
返回所有任务protected = False
并project.protected_tasks
返回相反的结果