2009-12-31 8 views
0

내가이 예를 들어 다음과 같은 문의 양식과 두 개의 PHONE_NUMBER 양식을 포함하여 양식을 반환하는 뷰를 생성 작성하면 인라인 양식에만 필요합니다 :장고 인라인 편집 적어도 하나 개의 필드가

multiple forms

전화 번호 양식은 사용자가 전화 번호 양식에 하나의 필드에 적어도 하나의 값을 삽입 한 경우에만 유효성을 검사해야합니다. 예 : 전화 번호는 유형과 번호가 있습니다. 사용자가 유형을 선택하면 번호가 필요합니다.

이제 뷰에서 사용자가 값을 삽입했는지/유형을 선택했는지 또는 숫자를 삽입했는지 확인할 수 있는지 궁금합니다. 모델을 인라인 편집하기 위해 관리자와 같이 작동해야합니다.

내보기는 다음과 같습니다

def contact_add(request): 
    user = request.user 
    if request.method == 'POST': 
     cform = ContactForm(request.POST) 
     pforms = [PhoneNumberForm(request.POST, prefix=str(x)) for x in range(0,3)] 
     if cform.is_valid() and all([pf.is_valid() for pf in pforms]): 
      new_contact = cform.save(commit=False) 
      new_contact.created_by = user 
      new_contact.save() 
      for pf in pforms: 
       new_phone_number = pf.save(commit=False) 
       new_phone_number.contact = new_contact 
       new_phone_number.save() 
      request.user.message_set.create(message='Contact %s has been added.' % new_contact.__str__()) 
      return HttpResponseRedirect("/crm/contacts/?oby=1") 

    else: 
     cform = ContactForm() 
     pforms = [PhoneNumberForm(prefix=str(x)) for x in range(0,3)] 

    return render_to_response(
     'crm/contact_add.html', 
     {'cform': cform, 'pforms': pforms,}, 
     context_instance = RequestContext(request), 
    ) 

편집 아래의 첫 번째 응답 후 :

내가 지정 유효성 검사에서이 작업을 수행하기 위해 시도했지만 만족스러운 말에 오지 않았다. 내 작업을 쉽게하기 위해 유스 케이스를 약간 변경했다. 나는 하나의 Contact Form과 하나의 Address Form을 포함하는 양식을 만든다. 주소 양식은 해당 주소를 만들지 않고 연락처를 만들 수 있어야하므로 주소 양식의 적어도 하나의 필드가 채워져있는 경우에만 유효성을 검사해야합니다. 내가 유효성 검사 오류를 제거하지 않습니다 이런 식으로하기 때문에,

class AddressForm(forms.ModelForm): 
    class Meta: 
     model = Address 
     exclude = ('contact',) 

    def clean(self): 
     cleaned_data = self.cleaned_data 
     street = cleaned_data.get("street") 
     postal_code = cleaned_data.get("postal_code") 
     city = cleaned_data.get("city") 
     country = cleaned_data.get("country") 

     if not street and not postal_code and not city and not country: 
      #searching a better idea here 
      return 0 
     else: 
      return cleaned_data 

하지만이 정말 도움이되지 않습니다

는 우선이처럼 보였다 손님 유효성 검사를 사용하려고 노력했다.

이것은 깨끗한 방법이이 유효성 검사를 수행하기에 잘못된 장소라는 것을 알았습니다. 주소 양식의 모든 값이 누락되었는지 POST.request에서 이미 확인해야한다고 생각합니다. 누락 된 경우 주소 양식에 is_valid()를 호출하지 않고 그냥 무시합니다. 하나 이상의 값을 사용할 수있는 경우 clean() 메서드를 재정의하지 않고 주소 양식의 일반 유효성 검사를 수행합니다.

좋은 아이디어입니까? 좋은 생각 인 경우, 어떻게하면 내 주소 양식의 값에 대한 POST 요청을 쉽게 확인할 수 있습니다.

아마 난`사고 방식 :-) 복잡한에

편집 :이 솔루션 사용 FormSets은 :

@login_required 
def contact_add(request): 
    user = request.user 
    if request.method == 'POST': 
     cform = ContactForm(request.POST) 
     phonenumberformset = PhoneNumberFormSet(request.POST) 

     if cform.is_valid() and classificationformset.is_valid() and addressformset.is_valid() and phonenumberformset.is_valid(): 
      new_contact = cform.save(commit=False) 
      new_contact.created_by = user 
      new_contact.save() 

      new_phonenumber_instances = phonenumberformset.save(commit=False) 
      for new_phonenumber in new_phonenumber_instances: 
       new_phonenumber.contact = new_contact 
       new_phonenumber.save() 

      request.user.message_set.create(message='Contact %s has been added.' % new_contact.__str__()) 
      return HttpResponseRedirect("/crm/contacts/?oby=1") 
    else: 
     cform = ContactForm() 
     #By default, when you create a formset from a model, the formset will use 
     #a queryset that includes all objects in the model (e.g., Author.objects.all()). 
     #Here we want to present an empty formset in order to add a new object 

     phonenumberformset = PhoneNumberFormSet(queryset=PhoneNumber.objects.none()) 
    return render_to_response(
     'crm/contact_add.html', 
     {'cform': cform, 'phonenumberformset': phonenumberformset,}, 
     context_instance = RequestContext(request), 
    ) 

inlineformset_factory를 사용하여이 또한 수행 할 수 있습니다, 내 다른 게시물을 참조 자세한 내용 : link

FormSets를 사용하는 경우 템플릿의 각 form_set에 대해 management_form을 포함해야합니다.

[u'ManagementForm data is missing or has been tampered with'] 

Using a formset inside a view is as easy as using a regular Form class. The only thing you will want to be aware of is making sure to use the management form inside the template.

{{ context.phonenumberformset.management_form }} 

답변

2

- 모든 것을 훨씬 쉽게 만들어 줄 것이며 실제로 관리자가 인라인 양식을 관리하는 방법입니다 (model formsets documentation 참조).

Formsset은 formset의 한 형식에 정보가 입력되지 않으면 필수 요소를 적용하지 않을 정도로 지능적입니다. 그러나 한 요소가 채워지면 모든 유효성 검사 요구 사항이 적용됩니다. 문제가 해결되어야하는 것 같습니다.

+0

Formsets? 결코 그것에 대해 들리지 않았다. 그것을 시도 할 것이다. 좋은 소리 :-) –

+0

하지만 위의 경우, 하나의 주소 양식에 대한 Formset을 만들면 위의 경우에 해당됩니다. formset은 사용자가 데이터를 채우지 않았으며 유효성을 검사하지 않을 것입니까? –

+0

좋습니다. 다른 인라인을 위해 그것을 시도하고 내 질문에 결과를 게시 할 것입니다! –

2

당신이 원하는 것은 양식에 custom validation을 정의 할 수 있습니다 : docs

그렇지 않으면이 오류가 발생합니다.

class PhoneNumberForm(forms.Form): 
    # Everything as before. 
    ... 

    def clean(self): 
     cleaned_data = self.cleaned_data 
     phone1 = cleaned_data.get("phone1") 

     if phone1: 
      # validate manually, and if it doesn't pass: 
      self._errors["phone1"] = ErrorList(["Hey, this field is wrong."]) 
      del cleaned_data["phone1"]    

     # Always return the full collection of cleaned data. 
     return cleaned_data 

그런 다음보기에서, 당신은 장고에 내장 된 오류 양식 유효성 검사 오류 처리에 의존 할 :

{{ pforms.phone1 }} 
{{ pforms.phone1.errors }} 
당신은 당신의 PHONENUMBER의 하위 폼에 대한 동적 접두사 장난이 아닌 formsets를 사용한다