5

私は Django 1.4 を使用していますが、フォームセットに苦労しています。ドキュメントと多くのSOの質問を読みました。それらが実際にどのように機能するかについての手がかりが得られていません。

- Fomset はこのように構成/宣言する必要がありますか?

forms.py と views.py でフォームセットを設定する方法。

forms.py: (forms.Form を宣言しました)

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

ビュー.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))

上記の 2 つの手順は正しいですか? フォームセットは正しく宣言されていますか?

さてテンプレ。私は次のように宣言しました。

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>

JavaScript の助けを借りて、コードは次のようなものを生成します。

<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>

出力は正しいですか?このように見えるべきですか?

- 検証、フォームセットを検証する方法は?

次に検証について。Form に forms.ChoiceField() があります

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

forms.ChoiceField() を選択肢のリストに対して検証する必要があることを読みました。私の質問は、どうすればこれを行うことができますか?

- いくつかの情報のデバッグ

clean() で pdb(python debuger) を使用すると、次のデータが得られます。

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']

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']}>

self.is_valid() のデバッグ:

(Pdb) self.is_valid()
False

このフォームセットを検証する方法についての手がかりはありますか?

よろしくお願いします、

4

1 に答える 1

0

上記formsetのコードのは正しく宣言されています。また、生成される出力は、フォームセットがどれだけ理想的に生成するかです。フォームの検証に関しては、簡単に行うことができます。

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

自分で検証を行う場合は、このメソッドがメソッドによって呼び出されるため、クラスcleanの下のメソッドをオーバーライドできます。formis_valid

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


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

検証を検討していて、フィールドが1つしかない場合はclean_field、次のようにメソッドをオーバーライドできます。

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

    def clean_bicycleaditemkindpropertyvalue(self):
        # Do single field validation here.
于 2013-01-11T16:15:39.140 に答える