2013-01-11 19 views
5

Używam Django 1.4 i walczę z Formsets. Czytałem dokumentację i wiele pytań SO. Wyciągam z nich wskazówki, jak naprawdę działają.Django Formsets - jak poprawnie zbudować zestaw i sprawdzić jego poprawność?

- Fomsets powinien być skonfigurowany/dclared w ten sposób?

W jaki sposób skonfigurowałem zestaw form w forms.py i views.py.

forms.py: (ja uznany za forms.Form)

class BicycleAdItemKindPropertyValueForm(forms.Form): 
    bicycleaditemkindpropertyvalue = forms.ChoiceField() 

views.py:

def submit_ad_view(request): 

    # This class is used to make empty formset forms required 
    class BicycleAdItemKindPropertyValueFormSet(BaseFormSet): 
     def __init__(self, *args, **kwargs): 
      super(BicycleAdItemKindPropertyValueFormSet, self).__init__(*args, **kwargs) 
      for form in self.forms: 
       form.empty_permitted = False 

     def clean(self): 
      pdb.set_trace() 
      for form in self.forms: 
       None 
      #form.fields['bicycleaditemkindpropertyvalue'] 

    formsetBicycleAdItemKindPropertyValue = formset_factory(BicycleAdItemKindPropertyValueForm, formset=BicycleAdItemKindPropertyValueFormSet) 

    if request.method == 'POST':  
     model_main = Main() 
     model_main.section = Section.objects.get(pk=request.POST['section']) 
     model_main.user = request.user 

     model_bicyclead = BicycleAd() 
     model_bicyclead.bicycleadtype = BicycleAdType.objects.get(pk=2) #1-Ad Link, 2-Ad Insite. Em principio ficara pre-definido 
     model_bicyclead.bicycleaditemkind = BicycleAdItemKind.objects.get(pk=4) 
     model_bicyclead.bicycleadcondition = BicycleAdCondition.objects.get(pk=2) 
     model_bicyclead.city = GeonamesLocal.objects.get(pk=4803854) 

     # Build the forms 
     form_main = MainForm(request.POST, instance = model_main) 
     form_bicyclead = BicycleAdForm(request.POST, instance = model_bicyclead) 
     form_bicycleadcategory = BicycleAdCategoryForm(request.POST) 
     form_bicycleaditemkindselect = BicycleAdItemKindSelectForm(request.POST) 
     formset_bicycleaditemkindpropertyvalue = formsetBicycleAdItemKindPropertyValue(request.POST) 

     #pdb.set_trace() 

     if form_main.is_valid() and form_bicyclead.is_valid() and form_bicycleadcategory.is_valid() and form_bicycleaditemkindselect.is_valid() and formset_bicycleaditemkindpropertyvalue.is_valid(): 
      main_f = form_main.save() 

      bicyclead_f = form_bicyclead.save(commit=False) 
      bicyclead_f.main = main_f 
      bicyclead_f.save() 

      bicycleadcategory_f = form_bicycleadcategory.save(commit=False, rel_obj=model_bicyclead) 


    else: 
     # Build the forms 
     form_main = MainForm() 
     form_bicyclead = BicycleAdForm() 
     form_bicycleadcategory = BicycleAdCategoryForm() 
     form_bicycleaditemkindselect = BicycleAdItemKindSelectForm() 
     formset_bicycleaditemkindpropertyvalue = formsetBicycleAdItemKindPropertyValue() 

    return render_to_response('app/submit/submit_ad.html', {'form_main': form_main, 'form_bicyclead': form_bicyclead, 'form_bicycleadcategory': form_bicycleadcategory, 'form_bicycleaditemkindselect': form_bicycleaditemkindselect, 'formset_bicycleaditemkindpropertyvalue': formset_bicycleaditemkindpropertyvalue}, context_instance=RequestContext(request)) 

Te dwa poprzednie kroki są poprawne? Formset jest zadeklarowany poprawnie?

Teraz szablon. Mam zadeklarowane tak:

sometemplate.html:

{{formset_bicycleaditemkindpropertyvalue.management_form}} 
{{formset_bicycleaditemkindpropertyvalue.non_form_errors}} 
{{formset_bicycleaditemkindpropertyvalue.errors}} 
{% for form in formset_bicycleaditemkindpropertyvalue.forms %} 
<div class="item-bicycleaditemkindpropertyvalue"> 
    <label for="{{form.bicycleaditemkindpropertyvalue.auto_id}}"></label> 
    {{form.bicycleaditemkindpropertyvalue}} 
</div> 

Z pomocą JavaScriptu, kod wygeneruje coś takiego:

<form action="/submeter/anuncio/" method="post"><div style="display: none;"><input type="hidden" value="3TWjKpqnXG7afZcvF1YmmWcRBKnYqePB" name="csrfmiddlewaretoken"></div> 
...   
     <div class="someclass"> 
      <input type="hidden" id="id_form-TOTAL_FORMS" value="1" name="form-TOTAL_FORMS"> 
      <input type="hidden" id="id_form-INITIAL_FORMS" value="0" name="form-INITIAL_FORMS"> 
      <input type="hidden" id="id_form-MAX_NUM_FORMS" name="form-MAX_NUM_FORMS"> 
      [] 
      <div class="item-bicycleaditemkindpropertyvalue"> 
       <label for="id_form-0-bicycleaditemkindpropertyvalue">Some 0</label> 
       <select id="id_form-0-bicycleaditemkindpropertyvalue" name="form-0-bicycleaditemkindpropertyvalue"> 
        ... 
       </select> 
      </div><div class="item-bicycleaditemkindpropertyvalue"> 
       <label for="id_form-1-bicycleaditemkindpropertyvalue">Some 1</label> 
       <select id="id_form-1-bicycleaditemkindpropertyvalue" name="form-1-bicycleaditemkindpropertyvalue"> 
        ... 
       </select> 
      </div> 
      <div class="item-bicycleaditemkindpropertyvalue"> 
       <label for="id_form-2-bicycleaditemkindpropertyvalue">Some 2</label> 
       <select id="id_form-2-bicycleaditemkindpropertyvalue" name="form-2-bicycleaditemkindpropertyvalue"> 
        ... 
       </select> 
      </div>  
     </div> 
     <input type="submit"> 
</form> 

To wyjście jest prawidłowy? Powinien wyglądać tak?

- Sprawdzanie poprawności, jak sprawdzić poprawność zestawu?

Teraz o walidacji. Mam forms.ChoiceField() w moim formularzu

class BicycleAdItemKindPropertyValueForm(forms.Form): 
    bicycleaditemkindpropertyvalue = forms.ChoiceField() 

Czytałem że forms.ChoiceField() powinny być zatwierdzone na liście wyborów. Moje pytanie brzmi: jak mogę to zrobić?

- Niektóre informacje debugowania

Korzystanie WPB (Python debuger) w czystym() Widzę Mam te dane:

class BicycleAdItemKindPropertyValueFormSet(BaseFormSet): 
    def __init__(self, *args, **kwargs): 
     super(BicycleAdItemKindPropertyValueFormSet, self).__init__(*args, **kwargs) 
     for form in self.forms: 
      form.empty_permitted = False 

    def clean(self): 
     pdb.set_trace() 
     for form in self.forms: 
      None 
     #form.fields['bicycleaditemkindpropertyvalue'] 

debugowania self.data:

(Pdb) self.data 
<QueryDict: {u'form-1-bicycleaditemkindpropertyvalue': [u'29'], 
      u'form-2-bicycleaditemkindpropertyvalue': [u'33'], 
      u'title': [u'adasd'], 
      u'form-MAX_NUM_FORMS': [u''], 
      u'country': [u'42'], 
      u'section': [u'5'], 
      u'item_kind': [u'4'], 
      u'form-INITIAL_FORMS': [u'0'], 
      u'bicycleadcategorytype': [u'3', u'2'], 
      u'csrfmiddlewaretoken': [u'3TWjKpqnXG7afZcvF1YmmWcRBKnYqePB'], 
      u'form-TOTAL_FORMS': [u'3'], 
      u'form-0-bicycleaditemkindpropertyvalue': [u'4']}> 

Debugowanie self.is_valid():

(Pdb) self.is_valid() 
False 

Jakieś wskazówki, w jaki sposób mogę sprawdzić poprawność tego zestawu?

Pozdrawiam,

Odpowiedz

0

formset w powyższym kodzie jest zadeklarowany poprawnie. Wygenerowane wyjście generuje również to, co najlepiej generuje. Jeśli chodzi o sprawdzanie poprawności formularza, możesz po prostu zrobić.

for form in formset: 
    if form.is_valid(): 
     # If is valid do something here 
    else: 
     # Do something Else 

jeśli chcesz robić rzeczy walidacji na własną rękę, można zastąpić metodę clean pod klasie form jako metoda ta nazywana jest metodą is_valid.

class BicycleAdItemKindPropertyValueForm(forms.Form): 
    bicycleaditemkindpropertyvalue = forms.ChoiceField() 


    def clean(self): 
     # Do field validation here. 

Jeśli szukasz, aby potwierdzić i tylko jedno pole można zastąpić metodę clean_field następująco:

class BicycleAdItemKindPropertyValueForm(forms.Form): 
    bicycleaditemkindpropertyvalue = forms.ChoiceField() 

    def clean_bicycleaditemkindpropertyvalue(self): 
     # Do single field validation here. 
+0

W formularzu mam zmieniona na „bicycleaditemkindpropertyvalue = forms.CharField (widget = forms.Select()) "i teraz mogę wyczyścić_ . Dzięki. –

Powiązane problemy