2011-02-09 2 views
15

이 내가 할 노력하고있어 대략입니다 : 사용자가이 "추가하기"버튼을 클릭하고 그 항목이 유효한 경우,Django : 양식을 만든 후 추가 양식을 추가하는 방법?

def post(request): 
    VehicleFormSet = formset_factory(StaffVehicleForm) 
    if request.method == 'POST': 
     vehicle_formset = VehicleFormSet(request.POST) 
     if 'add_vehicle' in request.POST: 
      if vehicle_formset.is_valid(): 
       form_count = vehicle_formset.total_form_count() 
       vehicle_formset.forms.append(vehicle_formset._construct_form(form_count)) 

을 기본적으로, 나는 해당 formset 또 다른 빈 양식을 추가하고 숨기려 이전 것.

위 코드의 문제점은 total_form_count()을 늘리는 방법을 알 수 없다는 것입니다. 지금 가지고있는 방식대로라면 번 다시 입력하면 아무 것도 나타나지 않을 것입니다. 아마도 form_count이 같기 때문일 것입니다. 나는 또한 _construct_form에 전화하고 내부에 의존하는 것을 좋아하지 않는다.

답변

3

자바 스크립트를 사용하여이 작업을 수행합니다. 해당 formset 세 관리 분야

<input type="hidden" id="id_TOTAL_FORMS" value="1" name="TOTAL_FORMS"> 
<input type="hidden" id="id_INITIAL_FORMS" value="1" name="INITIAL_FORMS">. 
<input type="hidden" id="id_MAX_NUM_FORMS" name="MAX_NUM_FORMS"> 

을 렌더링하기 때문에 당신은 id_TOTAL_FORMS 값을 증가 자바 스크립트를 사용하고, 단지 추가 필드에 추가 할 수 있습니다. 그래서 나는 다음과 같이 필드 세트를 만들 것입니다 :

VehicleFormSet = modelformset_factory(StaffVehicleForm, extra = 0, max_num = None) 

까다로운 것은 자바 스크립트에서 추가 양식 필드를 만드는 것입니다. 보통 AJAX를 사용하여 사용자 정의보기에서 새 행을 가져옵니다.

+4

이 BaseFormSet''에'empty_form' 속성이 여기에 사용 될 수 있습니다 다음은 해당 formset의 끝에서 (적어도) 하나 개의 빈 양식이 항상 있다는 것을 확인합니다. http://docs.djangoproject.com/ko/1.2/topics/forms/formsets/#empty-form "JavaScript를 사용하여 동적 양식에서보다 쉽게 ​​사용할 수 있도록 접두어가 __prefix__ 인 양식 인스턴스를 반환합니다."다음과 같이 유지할 수 있습니다. 내 생각에 복제 할 템플릿. –

+3

나는 JS에서 그것을하고 싶지 않다. ... – mpen

+0

Oh 좋은 팁 Reiner Gerecke! – Humphrey

8
class RequiredFormSet(BaseFormSet): 
    def add_form(self, **kwargs): 
     # add the form 
     tfc = self.total_form_count() 
     self.forms.append(self._construct_form(tfc, **kwargs)) 
     self.forms[tfc].is_bound = False 

     # make data mutable 
     self.data = self.data.copy() 

     # increase hidden form counts 
     total_count_name = '%s-%s' % (self.management_form.prefix, TOTAL_FORM_COUNT) 
     initial_count_name = '%s-%s' % (self.management_form.prefix, INITIAL_FORM_COUNT) 
     self.data[total_count_name] = self.management_form.cleaned_data[TOTAL_FORM_COUNT] + 1 
     self.data[initial_count_name] = self.management_form.cleaned_data[INITIAL_FORM_COUNT] + 1 

    def add_fields(self, form, index): 
     super(RequiredFormSet, self).add_fields(form, index) 
     form.empty_permitted = False 

그렇게 할 것입니다. 알아내는 데 7 시간 밖에 걸리지 않았습니다. 그리고 나는 여전히 초기 값을 망치지 않게하기 위해 왜 .is_bound = False이 필요한지 알지 못합니다.

+0

is_bound는 양식이 제출 된 POST에 바인딩되어 있지 않으면 항상 False 여야합니다. (또는 가져 오기). – Humphrey

+0

@ 흠 프리 : 예 ... 그렇습니다. 전체 formset입니다. 나는 공백이지만 아직 추가되지 않은 형태가 결속되기를 원하지 않는다. – mpen

+0

@mpen이 메소드를 어떻게 호출해야하며 어디에서 TOTAL_FORM_COUNT 개와 다른 변수를 얻을 수 있습니까? – CrazyGeek

0

후손을 위해 JS (또는 JS와 함께)없이 작동하고 formset 방법에 대한 자세한 지식이 필요하지 않은 또 다른 방법이 있습니다. 대신 POST 데이터를 검사하여 JS가 클라이언트 측에서 작업 한 것처럼 조정할 수 있습니다.

def hsview(request): 
    HS_formset = formset_factory(HSTestForm, extra=3) 
    prefix='XYZZY' 
    testinpost, empty = 'key', '' # field in the form and its default/empty value 
    extra=3 

# I prefer to do the short init of unbound forms first, so I invert the usual test ... 
    if request.method != 'POST': 

     formset = HS_formset(prefix=prefix) 
    else: 
     # process POSTed forms data. 
     # pull all relevant things out of POST data, because POST itself is not mutable 
     # (it doesn't matter if prefix allows in extraneous items) 

     data = { k:v for k,v in request.POST.items() if k.startswith(prefix) } 

     #if there are no spare empty forms, tell it we want another form, in place of or extra to client-side JS 
     #don't want to crash if unvalidated POST data is nbg so catch all ... 
     try: 
      n = int(data[ prefix + '-TOTAL_FORMS']) 
      test = '{}-{}-{}'.format(prefix, n-1, testinpost) 
      #print(test) 
      test = data.get(test, empty) 
     except Exception: 
      test = 'bleagh' 
      # log the error if it matters enough ... 
     if test != empty: 
      data[ prefix + '-TOTAL_FORMS'] = n + 1 

     # now the usual formset processing ... 
     formset = HS_formset(data, prefix=prefix) 
     # other_form = OtherForm(request.POST) 
     if formset.is_valid(): 
      ...    
관련 문제