Django: порядок Обновления приписывает для объектов в queryset

У меня есть атрибут на моей модели, чтобы позволить пользователю заказывать объекты. Я должен обновить порядок элемента в зависимости от списка, который содержит идентификаторы объекта в новом порядке; прямо сейчас я выполняю итерации по целому queryset и устанавливаю, каждый возражает после другого. Каков был бы самый легкий/самый быстрый способ сделать то же с целым queryset?

def update_ordering(model, order):
    """ order is in the form [id,id,id,id] for example: [8,4,5,1,3] """
    id_to_order = dict((order[i], i) for i in range(len(order)))
    for x in model.objects.all():
        x.order = id_to_order[x.id]
        x.save()
6
задан Bernhard Vallant 15 June 2010 в 18:58
поделиться

2 ответа

Это невозможно сделать за одну операцию с набором запросов. Насколько я знаю, это невозможно сделать даже в одном запросе с сырым SQL. Таким образом, вам всегда будет нужен вызов обновления для каждого объекта, который необходимо обновить. Таким образом, и ваше решение, и решения Коллина Андерсона кажутся вполне оптимальными для вашего описания.

Однако каков ваш вариант использования? Неужели весь список будет меняться каждый раз? В большинстве случаев это кажется маловероятным. Я вижу несколько разных подходов.

Вы сохраняете поле порядка, как вы говорите, но генерируете различие для списка заказов: def

update_ordering(model, order):
    """ order is in the form [id,id,id,id] for example: [8,4,5,1,3] """
    original_order = model.objects.value_list('id', flat=True).order_by('order')
    order = filter( lambda x: x[1]!=x[2], zip(xrange(len(order)), order, original_order))
    for i in order:
        model.objects.filter(id=i[1]).update(order=i[0])

Другой подход, в зависимости от того, что вы делаете, - это выполнить частичное обновление (например, с использованием AJAX), если это возможно, вместо того, чтобы обновлять весь переупорядоченный набор, просто обновляйте каждое обновление отдельно. Это часто увеличивает общую нагрузку, но со временем распределяет ее еще больше. Возьмем, к примеру, пошаговое перемещение 5-го элемента на место 2, это приведет к 3 заменам: (5,4); (4,3); (3,2). В результате будет 6 обновлений, тогда как при универсальном подходе потребуется всего 4. Но небольшие операции со временем будут разнесены.

5
ответ дан 17 December 2019 в 02:24
поделиться

Я не знаю, можно ли это сделать с помощью одного запроса, но это в любом случае эффективнее:

def update_ordering(model, order):
    """ order is in the form [id,id,id,id] for example: [8,4,5,1,3] """
    for id in model.objects.values_list('id', flat=True):
        model.objects.filter(id=id).update(order=order.index(id))
1
ответ дан 17 December 2019 в 02:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: