2013-03-04 6 views
6

Django 애플리케이션의 csv 가져 오기 양식을 만들고 유효성 검사를 위해 ModelFormSet에 가져올 행을 표시하려고합니다.Django가 ModelFormSet의 모든 양식에 대해 ForeignKey 옵션을 쿼리하지 못하게합니다.

따라서에 대한보기를 추가하여 csv에서 행을 읽고 ModelFormSet(queryset=an_empty_queryset, initial={data_from_the_csv})을 인쇄합니다.

문제는 모델이 데이터베이스 쿼리가 ModelChoiceField의 옵션을 채우기 위해 발행 된 해당 formset 각 양식의 각 필드 ForeignKey 필드를 통해 및 세 가지 다른 모델을 참조하는 것입니다.

Django가 양식을 여러 번 사용했는데 (왜 여러 번 사용했는지) 또는 아직이 작업을 수행하는 방법이 아직 모릅니다.

+1

django1.5 모델 메모리 캐시를 가지고있다. – danihp

+1

맞습니다 (https://docs.djangoproject.com/en/1.5/releases/1.5/#caching-of-related-model-instances).하지만 불행히도이 문제에는 영향을 미치지 않습니다. – jnns

+0

이 문제를 해결하기 위해 약간의 해킹을했습니다. http://stackoverflow.com/a/43105646/8450 –

답변

11

Django formsets는 양식 작성의 모든 세부 사항을 양식 오브젝트 자체에 위임하기 만하고 개별 양식 인스턴스는 다른 양식 인스턴스를 인식하지 않으므로 각 양식 인스턴스는 자체 선택 사항에 대해 조회해야합니다. 함수가받은 initial 데이터에 종속되어있을 수 있으므로 캐시 된 form 개체가 올바르지 않게 만드는 등 캐싱에 의도하지 않은 부작용이 발생할 수 있습니다.

쿼리 수를 줄이는 가장 좋은 방법은 선택한 쿼리 세트를 한 번 검색 한 다음 해당 쿼리를 생성자의 폼 클래스에 전달하는 것입니다. 사용자 정의 ModelForm 및 사용자 정의 ModelFormSet을 정의해야합니다.

직접 선택을 받아들이는 생성자가 필요합니다 양식 :

from django.forms.models import ModelForm 

class MyForm(ModelForm): 
    def __init__(self, my_field_choices=None, *args, **kwargs): 
     super(MyForm, self).__init__(*args, **kwargs) 
     self.fields['my_field'].choices = my_field_choices 

그리고 그들이 구축하고로의 formset은 검색어 세트를 실행하고 형태로 전달할 수있는 방법을 재정의해야합니다

from django.forms.models import BaseModelFormSet 

class MyFormSet(BaseModelFormSet): 
    def _construct_forms(self): 
     # instantiate all the forms and put them in self.forms 
     self.forms = [] 

     # Define each of your choices querysets 
     my_field_choices = Model.object.filter(...) 

     #Add your querysets to a dict to pass to the form 
     form_defaults = {'my_field_choices': my_field_choices, } 

     for i in xrange(min(self.total_form_count(), self.absolute_max)): 
      self.forms.append(self._construct_form(i, **form_defaults)) 

(이 어떻게 작동하는지에보고 the Django source 참조)

+0

제 질문에 답변 해 주셔서 감사합니다. 당신의 해결책은 내가 염두에 두었던 것이지만, 이제 이것이 이것이 갈 길이라는 것을 압니다! – jnns

+0

동일한 문제에 대해이 솔루션을 사용했지만 절약 할 때 "u'7 '을 할당 할 수 없습니다."Stop.city "는"City "인스턴스 여야합니다." Stop은 City fk가있는 ModelForm (formset을 빌드하는 데 사용됨)입니다. 당신이 그것을 지나칠 수있는 어떤 방법이 있습니까?, 이런 식으로 나아가는 것은 많은 오버 헤드가있는 것처럼 보입니다. – mariodev

+0

@mariodev, 문제를 설명하고 추적하는 데 도움이되는 코드가 더 필요할 수도 있습니다. 아마도이 정의를하기에는 의견이 충분하지 않을 수 있으므로 아마도 자신의 질문에 더 적합 할 것입니다. –