2016-10-21 4 views
0

MyModel.objects.filter(othermodel__nr='foo')으로 내 모델을 쿼리 할 수 ​​있습니다.Django ORM : 필터 조회를 통해 필드의 verbose_name 가져 오기

잘 작동합니다.

나는 verbose_name 필드에 있습니다.

예 : 위의 예는 쉽게 내가 OtherModel에 액세스 할 수 있습니다,하지만 난 그게 일반적인하고 싶으면 이후에

class OtherModel(models.Model): 
    nr=models.IntegerField(verbose_name='Number') 

.

여기서 "키"에 사용 된 필드의 자세한 이름을 얻는 방법은 무엇입니까?

MyModel.objects.filter(**{key: value})

나는 이중 밑줄을 해결하는 방법을 검색 할 수 있습니다. 이 예제에서는 "othermodel__nr"을 (예를 들어) "Number"로 설정합니다.

위의 예에서 업데이트

나는 참조 모델 OtherModel 것을 알고있다. 하지만 모든 문자열에 사용할 수있는 솔루션을 검색합니다. 이에 대한 ORM 필터링 필요한 이유를 이해가 안

get_verbose_name(str_containing_three_double_underscores) --> MyVerboseName 

답변

2

은 내가 모델의 맥락에서이 작업을 수행하는 것이 좋습니다 생각 @ MoisésHiraldo에 의견을 처리하기 위해.

from django.db.models.constants import LOOKUP_SEP 
from django.core.exceptions import FieldDoesNotExist 
from django.utils.encoding import force_text 

def get_verbose_name(model, lookup): 
    # will return first non relational field's verbose_name in lookup 
    for part in lookup.split(LOOKUP_SEP): 
     try: 
      f = model._meta.get_field(part) 
     except FieldDoesNotExist: 
      # check if field is related 
      for f in model._meta.related_objects: 
       if f.get_accessor_name() == part: 
        break 
      else: 
       raise ValueError("Invalid lookup string") 
     if f.is_relation: 
      model = f.related_model 
      continue 
     return force_text(f.verbose_name) 

get_verbose_name(MyModel, str_containing_three_double_underscores) 
+0

나는 본다. 당신은'lookup.split (LOOKUP_SEP)'를 사용하여 그것을 파싱한다. 좋아 보이고 ... 작동합니다. 고맙습니다. 나는 그것을 단순화하기 위해 작은 부분을 발견했다. 나는 너의 대답을 업데이트 할거야, 알았지? – guettli

+0

@guettli'LOOKUP_SEP'은'__'입니다. 그것은 단지 더 많은 DRY 이런 식으로)) –

+0

@ guettli 왜 매니저 부분을 삭제 했습니까? –

0

이 같은 예를 들면 다음과 같습니다에 대한

MyModel.objects.filter(**{str_containing_three_double_underscores: 'foo'}) 

내가 검색합니다. 귀하의 질문에 올바르게 대답했다면 필드의 자세한 이름을 원하는 클래스를 이미 알고 있습니까?

그렇다면 ModelName._meta.get_field('field_name').verbose_name을 사용하면 직접 ORM을 사용할 필요가 없습니다.

+0

감사합니다. 그 질문은 100 % 명확하지 않았습니다. 나는 그것을 새롭게했다. 질문은 지금 명확한가? – guettli

+0

모델과 필드 이름을 문자열로 사용하면 필터를 분할하고 ContentType을 @ moisés-hiraldo로 사용하는 것이 좋습니다. – ihhcarus

1

난 당신이 filter_key 항상 "model__field"로 끝나는 가정, 이런 식으로 뭔가를 할 수있을 것 같아요 :

from django.contrib.contenttypes.models import ContentType 

def get_verbose_name(filter_key): 
    model = filter_key.split("__")[-2] 
    field = filter_key.split("__")[-1] 
    content_type = ContentType.objects.get(model=model) 
    return content_type.model_class()._meta.get_field(field).verbose_name 
+0

예, 대부분의 경우이 방법이 효과적입니다. AFAIK 모델 이름은 고유하지 않습니다. 동일한 이름을 가진 두 개의 모델이있을 수 있습니다. (다른 앱에서 가져옴) ... – guettli

+0

필드 이름에서 오는 필터의 외래 키 이름이 실제 모델과 일치하지 않을 수도 있습니다 이름. 완전히 일반적인 것을 만들기 위해'filter_key'를 나눌 수 있고, 필드를 검사하고 주먹 아이템 (예 :'model._meta.get_field ("fk_field"). related_model')과 관계를 시작할 수 있습니다. –