Como você ordenar listas nas mesmas vias QuerySets são ordenados em Django?

votos
1

Eu tenho um modelo que tem um campo de ordenação sob sua classe Meta. Quando eu executar uma consulta e obter de volta um QuerySet para o modelo é na ordem especificada. No entanto, se eu tiver instâncias deste modelo que estão em uma lista e executar o método de classificação na lista a ordem é diferente do que eu quero. Existe uma maneira de classificar uma lista de instâncias de um modelo de tal forma que a ordem é igual ao especificado na definição do modelo?

Publicado 15/04/2009 em 21:57
fonte usuário
Em outras línguas...                            


3 respostas

votos
3

Não automaticamente, mas com um pouco de trabalho, sim. Você precisa definir uma função de comparação (ou CMP método na classe modelo) que pode comparar duas instâncias de modelo de acordo com o atributo relevante. Por exemplo:

class Dated(models.Model):
  ...
  created = models.DateTimeField(default=datetime.now)

  class Meta:
    ordering = ('created',)

  def __cmp__(self, other):
    try:
      return cmp(self.created, other.created)
    except AttributeError:
      return cmp(self.created, other)
Respondeu 16/04/2009 em 14:31
fonte usuário

votos
3

A resposta à sua pergunta é diferentes graus de sim, com alguns requisitos manuais. Se por listvocê quer dizer um querysetque foi formada por alguns consulta complicada, então, com certeza:

queryset.order_by(ClassName.Meta.ordering)

ou

queryset.order_by(instance._meta.ordering)

ou

queryset.order_by("fieldname") #If you like being manual

Se você não está trabalhando com um queryset, então é claro que você ainda pode tipo, da mesma forma que qualquer pessoa classifica objetos complexos em python:

  • comparadores
  • especificando chaves
  • Decore / Ordenar / undecorate

Veja a wiki python para uma explicação detalhada de todos os três.

Respondeu 15/04/2009 em 22:23
fonte usuário

votos
2

Com base na resposta de Carl, você pode facilmente adicionar a capacidade de usar todos os campos pedidos e até mesmo detectar os que estão na ordem inversa.

class Person(models.Model):
  first_name = models.CharField(max_length=50)
  last_name = models.CharField(max_length=50)
  birthday = date = models.DateField()

  class Meta:
    ordering = ['last_name', 'first_name']

  def __cmp__(self, other):
    for order in self._meta.ordering:
      if order.startswith('-'):
        order = order[1:]
        mode = -1
      else:
        mode = 1
      if hasattr(self, order) and hasattr(other, order):
        result = mode * cmp(getattr(self, order), getattr(other, order))
        if result: return result
    return 0
Respondeu 16/04/2009 em 23:17
fonte usuário

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