Esto no se puede hacer en una sola operación queryset. Hasta donde yo sé, ni siquiera se puede hacer en una consulta con SQL sin formato. Por lo tanto, siempre necesitará la llamada de actualización para cada objeto que deba actualizarse. Entonces, tanto su solución como la de Collin Anderson parecen ser óptimas para su descripción.
Sin embargo, ¿cuál es su caso de uso? ¿Realmente toda la lista va a cambiar todo el tiempo? En la mayoría de las situaciones esto parece muy poco probable. Puedo ver algunos enfoques diferentes.
Se ahorra el campo orden como usted dice, pero se genera un diff de la lista de pedidos: 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])
Otro enfoque, dependiendo de lo que está haciendo es hacer una actualización parcial (por ejemplo, utilizando AJAX) si es posible, en lugar de actualizar todo el conjunto reordenado, simplemente actualice cada actualización por separado. Esto a menudo aumentará la carga total, pero se extenderá más con el tiempo. Tomemos, por ejemplo, mover el quinto elemento paso a paso al lugar 2, esto introducirá 3 intercambios: (5,4); (4,3); (3,2). Resultando en 6 actualizaciones, mientras que con el enfoque "todo en uno" solo se necesitarán 4. Pero las operaciones pequeñas se extenderán a lo largo del tiempo.
Supongo que solo ahorra al golpear el db una vez para obtener todos los elementos (todos los elementos tienen que actualizarse, por lo que su solución también itera sobre todos ellos). –