2011-09-09 16 views
14

に秩序を維持していない私はIDが持っている特定の順序ジャンゴ:__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] 

に私はalbum_idsのidのように、そのために、クエリセットでアルバムを必要とします。誰でも注文を維持する方法を教えてください。またはalbum_idsのようにアルバムを入手できますか?

答えて

13

IDのリストが大きすぎではない、あなたがリストにQSを変換し、Pythonでそれをソートしたと仮定すると:

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

私は大規模なデータベースを持っており、IDは何百万にもなる可能性があります。 – Ahsan

+0

今後の参考のために、IDが何百万ものものになるという事実は、そのような量の情報をロードする必要があります。代わりに、django-paginationを使用すると、表示に必要な量だけを読み込んで、より良いユーザーエクスペリエンスを実現できます。 –

+1

これは良い解決策ですが、それに取り組むためにQuerySetを保持する方法はありますか? –

9

あなたはORMを経由してジャンゴにそれを行うことはできません。 しかし、それは自分自身で実装するのは非常に簡単です:

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

Djnago 1.8ので、この方法で

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

最終結果がリストを生成する他の回答とは対照的にクエリーセットであるため、これは素晴らしいです。 –

+0

ベスト・アンサー!ありがとうArun! – nextdoordoc

1

を行うことができますあなたはextraクエリセット修飾子

>>> 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']) 
を使用してORMを経由してジャンゴにそれを行うことができます