2011-09-09 7 views
14

ho ID di in un ordine specificodjango: __in lookup query non mantenere l'ordine in querset

>>> album_ids = [24, 15, 25, 19, 11, 26, 27, 28] 
>>> albums = Album.objects.filter(id__in=album_ids, published= True) 
>>> [album.id for album in albums] 
[25, 24, 27, 28, 26, 11, 15, 19] 

ho bisogno album in set di query in questo ordine come id in album_ids. Qualcuno, per favore, dimmi come posso mantenere l'ordine? o ottenere gli album come in album_ids?

risposta

13

Supponendo che l'elenco di ID non è troppo grande, si potrebbe convertire il QS per una lista e ordinare in Python:

album_list = list(albums) 
album_list.sort(key=lambda album: album_ids.index(album.id)) 
+0

Ho un database di grandi dimensioni, gli ID possono essere in milioni – Ahsan

+0

Solo per riferimento futuro, penso che il fatto che gli ID possano essere milioni non è rilevante nella maggior parte delle applicazioni perché È necessario caricare una tale quantità di informazioni. Invece, puoi utilizzare django-pagination che carica solo la quantità necessaria per la visualizzazione e migliora la user experience. –

+1

Questa è una bella soluzione, ma come fare per mantenere il QuerySet da seguire lavorando su di esso? –

9

Non si può fare in Django via ORM. Ma è abbastanza semplice da implementare da youself:

album_ids = [24, 15, 25, 19, 11, 26, 27, 28] 
albums = Album.objects.filter(published=True).in_bulk(album_ids) # this gives us a dict by ID 
sorted_albums = [albums[id] for id in albums_ids if id in albums] 
17

Dal Djnago 1.8 si può fare in questo modo

from django.db.models import Case, When 

pk_list = [10, 2, 1] 
preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(pk_list)]) 
queryset = MyModel.objects.filter(pk__in=pk_list).order_by(preserved) 
+2

Questo sembra ottimo perché il risultato finale è un queryset in contrapposizione alle altre risposte che producono elenchi. –

+0

La migliore risposta! Grazie Arun! – nextdoordoc

1

È possibile farlo in Django tramite ORM utilizzando il modificatore extra QuerySet

>>> album_ids = [24, 15, 25, 19, 11, 26, 27, 28] 
>>> albums = Album.objects.filter(id__in=album_ids, published= True 
      ).extra(select={'manual': 'FIELD(id,%s)' % ','.join(map(str, album_ids))}, 
        order_by=['manual'])