2013-09-16 2 views
0

서로 다른 시간대에 공통 필드 이름으로 유사하게 필터링하려는 두 가지 모델이 있으므로 두 모델 모두를 처리하는 단일 컨텍스트 함수를 다음과 같이 작성했습니다. 모델명으로 사용할 인수. 지금은 eval()을 사용하고 있지만, 내 직감에서 뭔가 심각한 오류라고 알려줍니다. 내가 묘사하는 것을 수행하는 더 평범한 방법이 있습니까? 비슷한 방식으로 키워드를 전달하는 방법,이 두 번째로모델 이름을 문자열로 전달하는 모범 사례

def reference_context(model, value): 
    menu = main_menu() 
    info = company_info() 
    pages = get_list_or_404(eval(model), category = value) 

그래서 나는의 라인을 따라 뭔가를 할 수 : 여기

내 코드는 순간의 모습의 단축 버전입니다 :

def reference_context(model, category, value): 
    menu = main_menu() 
    info = company_info() 
    pages = get_list_or_404(eval(model), eval(category) = value) 

기타 문제에 대한 설명은 환영하며 적극 권장합니다.

+0

왜 문자열로하지 참고로 모델을 통과해야합니까? 예 : reference_context (MyModel, value) –

+0

내가 아는 한 그렇게 일반적인 것이 아닙니다. 그런 경우에는 필자가 명시 적으로 이름 -> 모델 (간단한 dict이 수행 할 것입니다.)의 레지스트리를 만들고이를 사용합니다. 이렇게하면 누군가가 양식에 "사용자"를 모델로 주입 할 때 예상치 못한 보안 문제를 피할 수 있습니다. –

답변

1

그들은 동일한 모듈 (models.py)이 방법, 당신은 모델 클래스를 검색 할 getattr을 사용할 수 있으며, kwargs (이중 별표와 DICT)에서 오는 경우 :

from myapp import models 

def reference_context(model, value): 
    menu = main_menu() 
    info = company_info() 
    pages = get_list_or_404(getattr(models, model), **{category: value}) 
1

당신은 get_model을 사용할 수 있습니다 유틸리티 함수는 앱 이름과 모델 이름을 사용합니다.

from django.db.models import get_model 
User = get_model("auth", "User") # returns django.contrib.auth.models.User 
1

모델 참조를 전달하면 모델을 문자열로 전달해야하는 이유가 실제로 들지 않습니다. 예 :

class ModelA(models.Model): 
    ... 

class ModelB(models.Model): 
    ... 

def reference_context(model, **kw): 
    menu = main_menu() 
    info = company_info() 
    pages = get_list_or_404(model, **kw) 
    # ... 

이 설정에서는 원하는 모든 모델과 원하는 검색어를 전달할 수 있습니다. 예 : 당신이 정말로, 모델 문자열을 매핑 명시 적 레지스트리/매핑을 사용해야하는 경우

reference_context(ModelB, item__ordered__lte=now) 

으로

reference_context(ModelA, category="Hello") 

또는

는, 내 댓글에 설명했다. 이는 "책"예를 들어, 그들 대신에 사용자를 만들 수 있습니다 양식 데이터를 조작하는 사람들을 방지 :

model_map = dict(book=ModelA, magazine=ModelB) 
reference_context(model_map[model_as_string], ...) 
관련 문제