Как отфильтровать набор запросов django на основе пар полей из другого набора запросов? - PullRequest
0 голосов
/ 22 октября 2019

У меня есть таблица, которая обрабатывает порядок задач, и у каждого пользователя может быть свой порядок для одной и той же задачи. Это может быть трудно объяснить, поэтому у меня есть отдельный пример внизу этого поста.

Объект, представляющий порядок задач для каждого пользователя:

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

Я действительно надеюсь, что объяснил это хорошодостаточно!

...