ordenação personalizada em Django

votos
25

Como você define uma ordenação específica no Django QuerySets?

Especificamente, se eu tiver um QuerySetassim: ['a10', 'a1', 'a2'].

Ordem regular (usando Whatever.objects.order_by('someField')) vai dar-me ['a1', 'a10', 'a2'], enquanto eu estou procurando: ['a1', 'a2', 'a10'].

O que é a maneira correta para definir minha própria técnica de ordenação?

Publicado 19/05/2009 em 16:49
fonte usuário
Em outras línguas...                            


4 respostas

votos
40

Tanto quanto eu estou ciente, não há nenhuma maneira de especificar ordenação do lado do banco de dados, desta forma, uma vez que seria muito específicas de backend. Você pode querer recorrer a boa classificação Python à moda antiga:

class Foo(models.Model):
    name = models.CharField(max_length=128)

Foo.objects.create(name='a10')
Foo.objects.create(name='a1')
Foo.objects.create(name='a2')

ordered = sorted(Foo.objects.all(), key=lambda n: (n[0], int(n[1:])))
print ordered # yields a1, a2, 10

Se você achar que precisa deste tipo de ordenação de um monte, eu recomendo fazer um costume models.Managersubclasse para o seu modelo que executa a ordenação. Algo como:

class FooManager(models.Manager):
    def in_a_number_order(self, *args, **kwargs):
        qs = self.get_query_set().filter(*args, **kwargs)
        return sorted(qs, key=lambda n: (n[0], int(n[1:])))

class Foo(models.Model):
    ... as before ...
    objects = FooManager()

print Foo.objects.in_a_number_order()
print Foo.objects.in_a_number_order(id__in=[5, 4, 3]) # or any filtering expression
Respondeu 19/05/2009 em 17:03
fonte usuário

votos
26

@ Resposta de Jarret (fazer o tipo em Python) funciona muito bem para casos simples. Assim que você tem uma grande mesa e quiser, digamos, puxar apenas a primeira página de resultados ordenados de uma certa maneira, esta abordagem breaks (você tem que puxar cada linha do banco de dados antes que você pode fazer o tipo). Nesse ponto eu iria olhar para adicionar um "tipo" desnormalizado campo que você preencher no campo "nome" no save-tempo, que você pode classificar no nível de DB da maneira usual.

Respondeu 20/05/2009 em 19:20
fonte usuário

votos
0

Se você tiver conjuntos de dados maiores e, adicionalmente, usar um backend SOLR (por exemplo, com Haystack):

Use solr.ICUCollationFieldcom a numeric=trueopção de tipo para os campos de classificação. Isto irá classificar de acordo com a linguagem e se os números estão presentes irá classificar o número de peça de acordo com as regras numéricas em vez de triagem string.

Veja: https://cwiki.apache.org/confluence/display/solr/Language+Analysis#LanguageAnalysis-UnicodeCollation http://www.solr-start.com/javadoc/solr-lucene/org/apache/solr/schema /ICUCollationField.html

Respondeu 04/11/2014 em 09:31
fonte usuário

votos
0

Depende de onde você quer usá-lo.

Se você quiser usá-lo em seus próprios modelos, gostaria de sugerir a escrever um modelo-tag, que vai fazer a encomenda para você Nele, você pode usar qualquer algoritmo de ordenação que pretende utilizar.

No administrador Eu classificação personalizada estendendo os modelos para as minhas necessidades e carregar um modelo-tag como descrito acima

Respondeu 19/05/2009 em 17:04
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more