django字段/小部件,用于多个值

时间:2012-11-07 23:01:04

标签: django django-forms

我真的无法弄清楚如何设法做到这一点。

我想使用django表单来验证以下内容(aname的未知数量):

<input type="hidden" name="aname" value="someJSONdump1"/>
<input type="hidden" name="aname" value="someJSONdump2"/>
<input type="hidden" name="aname" value="someJSONdump3"/>
<input type="hidden" name="aname" value="someJSONdump4"/>

在django方面,我在打电话:

form = myforms.MyForm(request.POST, request.FILES)
if (form.is_valid()):
    # do something
else:
    # redisplay the form

如何定义MyForm以允许我验证每个aname以及错误时窗口小部件重新显示上述<input>s

我无法弄清楚如何使用MultiValueField,或者即使它是正确的使用方法。当你知道你有多少个字段时,这似乎是一个解决方案?

在表单中使用clean_aname()没有任何帮助,因为self.cleaned_data.get('aname')只是最后一个值。

如果没有表单,我会使用类似request.POST.getlist('aname')的内容,但如果我可以使用django.forms执行此操作,我希望避免这种情况。

感谢您的帮助。


修改

我离开了,我正在从ModelForm定义更多字段。我认为这可能会对formset产生一些影响。这就是我所处的位置......这个解决方案被认为是“Django形式”兼容吗?

class MyField(forms.Field):
    widget = MyWidget

    def to_python(self, value):
        if (isinstance(value, basestring)):
            value = [value]
        return [json.loads(v) for v in value]

class MyForm(forms.ModelForm):
    class Meta:
        model = models.MyModel

    aname = MyField()

    def clean(self):
        cleaned_data = super(MyForm, self).clean()
        cleaned_data['aname'] = self.fields['aname'].clean(self.data.getlist('aname'))
        return cleaned_data

现在,我必须定义MyWidget以允许我显示<input type="hidden">的列表,但我想知道这个解决方案是否合理。也许我也可以在clean_aname()中完成此任务。

2 个答案:

答案 0 :(得分:0)

您可以尝试使用一组表单(在Django中称为formset)来实现它,其中每个表单都是您想要的验证表单的实例。例如,

class ValidationForm(forms.Form):
    aname = forms.CharField()

    def clean_aname(self):
        aname = self.cleaned_data['aname']
        # TODO validate aname
        return aname

    def save(self, commit=False):
        # TODO implement this form's save logic
        return 'It works!'

要创建一组表格(请参阅formset documentation),请执行:

from django.forms.formsets import formset_factory
ValidationFormSet = formset_factory(ValidationForm)

在您的视图中,使用ValidationFormSet接收数据:

def my_view(request):
    if request.method == 'POST':
        form = ValidationFormSet(request.POST, request.FILES)

        if form.is_valid():
            # All anames were validated by clean_aname
            results = form.save()

            for r in results:
                print r # Should print 'It works!'
    else:
        form = ValidationFormSet()

    return <your_result>

答案 1 :(得分:0)

您可以使用前缀将多个表单传递给视图,如下所示:

jsondumplist = ['jsondump1', 'jsondump2', 'jsondump3', 'jsondump4'....]
if request.method == 'POST':
        forms = [YourForm(request.POST, prefix=x) for x in jsondumplist]                        
        for f in forms:
                if f.is_valid():
                        f.save()                 
else:
        forms = [YourForm(prefix=x) for x in jsondumplist]

YourForm可能只有你感兴趣的单个字段,或几个。

class YourForm(forms.Form):
    aname = forms.CharField(widget=forms.HiddenInput())

然后,您的模板将如下所示:

{% for form in forms %}
    {% for field in form %}
        {{ field }}
    {% endfor %}
{% endfor %}