如何根据另一个查询集的字段对过滤Django查询集?

时间:2019-10-22 18:35:13

标签: python django database django-models django-rest-framework

我有一个处理任务顺序的表,每个用户对同一任务可以有不同的顺序。这可能很难解释,所以我在这篇文章的底部有一个独立的示例。

代表每个用户的任务顺序的对象:

class TaskOrdering(models.Model):
    task = models.ForeignKey(Task, related_name='ordering')
    user = models.ForeignKey(User, related_name='task_ordering')
    order = models.PositiveIntegerField(null=True)

删除任务时,我需要递减每个用户视图中所有任务的顺序,该顺序的顺序要大于已删除任务的顺序。但是,由于每个用户都有自己的任务列表视图,因此该删除任务的顺序对于每个用户都是不同的。

现在我正在做

# Instance is a Task object
def perform_destroy(self, instance): 

    # deleted_task_ordering is a set of TaskOrdering objects
    # representing the order of the task in EACH user's view
    deleted_task_ordering = instance.ordering.all()

    # deleted_task_ordering is a set of TaskOrdering objects
    # representing the order of OTHER tasks in EACH user's view
    other_tasks_ordering = TaskOrdering.objects.exclude(task=instance)

    for o in deleted_task_ordering:
        need_decrement = other_tasks_ordering.filter(user=o.user, order__gt=o.order)
        need_decrement.update(order=F('order') - 1)

这可行,但是必须使用Django查询而不是for循环,这是一种更有效的方法。我苦苦挣扎的原因是因为TaskOrdering查询集过滤器需要匹配deleted_task_ordering中的字段对。我知道我也可以在一个循环中构建过滤器查询并进行一次批量更新,但是我正试图完全摆脱for循环。

例如,如果删除具有3个用户的任务,则deleted_task_ordering可能是:

[
    {task: 1, user: 1, order: 3},
    {task: 1, user: 2, order: 5},
    {task: 1, user: 3, order: 2}
]

然后,我需要使用TaskOrdering过滤器来返回以下所有对象:

User = 1 AND order > 3 +
User = 2 AND order > 5 +
User = 3 AND order > 3

我真的希望我能解释得足够好!

0 个答案:

没有答案