2010-09-02 32 views
13

Bir ids/pks listesi verildiğinde, listedeki dizine göre sıralanmış bir QuerySet nesne oluşturmak istiyorum.Django QuerySet Özel Sipariş İste göre

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

Elbette bu nesneleri döndürür, ancak modelleri meta sipariş mülkiyet sırasına göre, ben pk s sırasına göre kayıtlarını almak isteyen:

Normalde ile başlayan ediyorum pk_list.

Sonuçta ben Django'nın ModelMultipleChoiceField form alanına sipariş QuerySet geçmek istedikleri gibi birQuerySet nesne (bir liste) olmak zorundadır.

+1

db seviyesinde MySQL & PostgreSQL için: http://blog.mathieu-leplatre.info/django-create-a-queryset-from-a-list-preserving-order.html – Medorator

cevap

1

Bunu bir filtre koşulu kullanarak yapmanın bir yolunu bilmiyorum. Veritabanınız satırları IN maddesinin sırasına göre döndürürse, adresinden Django'nun extra yöntemini, bunu elde etmek için veritabanınız tarafından sağlanan ROWNUM ile birleştirebilirsiniz. örneğin İçin

.: row_num() geçerli satırın satır numarasını döndürür bir veritabanı işlevi olduğu varsayılır

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

. Postgresql 8.4+ row_num()'u destekler, ancak IN maddesindeki değerler ile aynı sıra kullanılarak döndürülen satırların nasıl sipariş edileceğini bilmiyorum.

Sanırım ModelMultipleChoiceField alt sınıfının daha iyi bir yolu olacak ve oluştururken özel sıralama mantığı ekleyeceğim.

+0

Bunun için teşekkürler, ancak sqlite ve mysql ile uyumlu olacak bir şeye ihtiyacım var. Ben düşünüyorum düşünüyorum "MultipleChoiceField" kullanarak ve seçim listesi kendim oluşturuyorum. –

7

Bunu yapmak için yerleşik bir yol yoktur.

MySQL kullanıyorsanız, modelinizde özel bir sıralama sırası oluşturmak için bu veritabanının FIELD() işlevini kullanabilir ve bu şekilde sıralayabilirsiniz. Bu işe yarar:

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

Bunun için teşekkürler, ancak sqlite ve mysql ile uyumlu olacak bir şeye ihtiyacım var. Ben düşünüyorum düşünüyorum "MultipleChoiceField" kullanarak ve seçim listesi kendim oluşturuyorum. –

+0

wait, 'order_by = 'pk' çalışmıyor mu? – amirouche

+1

@amirouche, hayır, basit sayısal sıralamadan tamamen farklı bir sırayla istiyor. – LarrikJ