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

Dan*_*ure 5 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"/>
Run Code Online (Sandbox Code Playgroud)

在django方面,我打电话给:

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

我如何定义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
Run Code Online (Sandbox Code Playgroud)

现在,我必须定义MyWidget允许我显示一个列表<input type="hidden">,但我想知道这个解决方案是否可以接受.也许我也可以做到这clean_aname()一点.

小智 0

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

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!'
Run Code Online (Sandbox Code Playgroud)

要创建一组这些表单(请参阅表单集文档),请执行以下操作:

from django.forms.formsets import formset_factory
ValidationFormSet = formset_factory(ValidationForm)
Run Code Online (Sandbox Code Playgroud)

在您看来,使用 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>
Run Code Online (Sandbox Code Playgroud)