2011-04-30 3 views
1

QuerySet의 객체가 String으로 평가되는 방식에 따라 QuerySet을 정렬하려고합니다. 방법이 있는지 궁금 해요Django QuerySet order_by string evaluation

System.objects.filter(...).order_by('__unicode__') 

: 나는 같은 쿼리 뭔가를 할 수 있도록하고 싶습니다,

class System(models.Model): 
    operating_system = models.CharField(...) 
    language = models.CharField(...) 
    locale = models.CharField(...) 

    def __unicode__(self): 
    def __clean(orig, new): 
     if orig is None or orig == "": 
     if new is None or new == "": 
      return "" 
     else: 
      return str(new) 
     else: 
     if new is None or new == "": 
      return str(orig) 
     else: 
      return str(orig) + " " + str(new) 
    name = None 
    for attr in System._meta.fields: 
     if attr.name != "id": 
     name = __clean(name, getattr(self, attr.name)) 
    for m2mfield in System._meta.many_to_many: 
     for object in getattr(self, m2mfield.name).all(): 
     name = __clean(name, object) 

    if name == "": 
     return "Undefined" 
    return name 

을 그리고 :

그래서 내 모델은 다음과 같이 보입니다 맞춤 관리자없이이 작업을 수행 할 수 있습니다.

감사합니다.

+0

* 사용자 정의 관리자로도 * 할 수 없습니다. –

+1

해커가 아닌 문자열 값인 비정규 화 된 필드를 저장하는 것이 좋습니까? 귀하의 시스템 모델에 다른 필드를 던져서 아마도 save()를 재정 의하여 필요한 것으로 업데이트 한 다음이 다른 필드로 주문하면됩니다 ... – Henry

+0

@Henry는 비정규 필드와 필드의 차이점을 자세히 설명 할 수 있습니까? 나는 현재 사용하고 있습니다 (또는 포인터를주세요)? 감사합니다. 그건 분명히 효과가있을 수 있습니다. 공간이 약간 낭비되는 느낌이 들지만? –

답변

1

__unicode__에는 결국 System 개체를 나타내는 단일 문자열로 끝납니다. 필요에 따라 매번 계산하는 대신 한 번 계산하여 모델에 저장하십시오.

class System(models.Model): 
    operating_system = models.CharField(...) 
    language = models.CharField(...) 
    locale= models.CharField(...) 
    name = models.CharField(editable=False, ...) 

    def save(self, *args, **kwargs): 
     self.name = self._calculate_name() 
     super(System, self).save(*args, **kwargs) 

    def __unicode__(self): 
     return self.name 

    def _calculate_name(self): 
     # all that string manipulation and relationship stuff 

이제이 방법 몇 가지주의 사항이 있습니다 쉽게

System.objects.filter(...).order_by('name') 

이 이름으로 주문할 수 있습니다, 정말 시스템의 사용에 따라 달라집니다. 또한, 공간에 대해 걱정하지 마세요, 그건 제 의견입니다!


유의점이 필드를 역 정규화, 정규화 얼굴이없는 동일한 다른 문제 관계형 데이터 앓고 있기 때문에

에서 확장. Denormalizationname이 의존하는 필드 또는 관계를 메서드보다 다른 경로를 통해 변경하는 경우 name으로 변경하지 않고 변경할 수 있습니다. 또한 쓰기 속도를 저하시킬 수 있습니다 (이 경우에는 작은 금액), 공간 요구 사항을 늘릴 수 있습니다. (제 의견으로는 여기에 다시 문제가되지 않습니다.) 그리고 Google이 확신할만한 기타 물건들로 가득 찼습니다.

예를 들어 시스템을 건드리지 않고 OS의 설명을 변경할 수있는 OS 테이블이있는 경우에는주의해야합니다. 테이블, n .name은 OS에 저장되지 않아 업데이트되지 않으므로 다시 계산해야합니다. 이 같은 신호를 돕고 더 많은 방법을 무시하는 메커니즘이 있습니다. 필요에 따라 일괄 적으로 업데이트 할 수도 있습니다.

실제로 여기에 완전히 설명되지 않은 사용 사례에 크게 의존합니다. SO는 유스 케이스를보다 완벽하게 제시하면 최상의 솔루션을 좁히는 데 도움이 될 수있는 사람들로 가득합니다.

+0

감사합니다 Henry! 이것은 아마 그것을 할 것입니다. 이 접근법에 대한 단서를 간단히 넓힐 수 있습니까? –

관련 문제