2010-09-02 21 views
13

Dada una lista de ids/pks, me gustaría generar un QuerySet de los objetos ordenados por el índice en la lista.Pedido personalizado Django QuerySet por ID

Normalmente me gustaría empezar con:

pk_list = [5, 9, 2, 14] 
queryset = MyModel.objects.filter(pk__in=pk_list) 

Por supuesto, esto devuelve los objetos, pero en el orden de los modelos de propiedad de ordenación del meta, y deseo de obtener los registros en el orden de los pk s en pk_list.

resultado El final tiene que ser unoQuerySet objeto (no una lista), como deseo de pasar el QuerySet ordenado campo ModelMultipleChoiceField forma de Django.

+1

A nivel db para MySQL y PostgreSQL: http://blog.mathieu-leplatre.info/django-create-a-queryset-from-a-list-preserving-order.html – Medorator

Respuesta

1

No conozco una forma de hacerlo utilizando una condición de filtro. Si su base de datos devolverá las filas en el orden de la cláusula IN, entonces puede ser capaz de combinar el método extra de Django con el ROWNUM provisto por su base de datos para lograr esto.

Por ej .:

queryset = MyModel.objects.filter(pk__in=[pk_list]).extra(
     select: {'rownum': 'row_num()'}).order_by('rownum') 

Dónde row_num() se supone que es una función de base de datos que devuelve el número de fila de la fila actual. Postgresql 8.4+ admite row_num() pero no sé cómo ordenar las filas devueltas utilizando el mismo orden que los valores en la cláusula IN.

Creo que una mejor manera sería la subclase ModelMultipleChoiceField y agregar lógica de ordenación personalizada al renderizar.

+0

Gracias por esto, pero necesito algo que sea compatible con sqlite y mysql. Creo que usaré 'MultipleChoiceField' y generaré la lista de opciones yo mismo. –

7

No hay una forma integrada de hacerlo.

Si está utilizando MySQL, puede usar la función de esa base de datos FIELD() para configurar una secuencia de pedido personalizada en su modelo, y ordenar por eso. Esto funcionaría:

pk_list = [5, 9, 2, 14] 
ordering = 'FIELD(`id`, %s)' % ','.join(str(id) for id in pk_list) 
queryset = MyModel.objects.filter(pk__in=[pk_list]).extra(
       select={'ordering': ordering}, order_by=('ordering',)) 
+0

Gracias por esto, pero necesito algo que sea compatible con sqlite y mysql. Creo que usaré 'MultipleChoiceField' y generaré la lista de opciones yo mismo. –

+0

espera, 'order_by = 'pk'' no funciona? – amirouche

+1

@amirouche, no lo quiere en un orden completamente diferente al tipo numérico simple. – LarrikJ

Cuestiones relacionadas