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,
W formularzu mam zmieniona na „bicycleaditemkindpropertyvalue = forms.CharField (widget = forms.Select()) "i teraz mogę wyczyścić_. Dzięki. –