首页 > 解决方案 > 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_tasksproject.tasks.protected

标签: django

解决方案


这是我想出的一个解决方案——这个想法是朝着另一个方向发展。我相信有更优雅的方法可以做到这一点。

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返回相反的结果


推荐阅读