Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在django表单中多次重复单个字段_Python_Django_Forms_Django Forms - Fatal编程技术网

Python 在django表单中多次重复单个字段

Python 在django表单中多次重复单个字段,python,django,forms,django-forms,Python,Django,Forms,Django Forms,警告:我知道Fieldset,但仍然不相信它们是实现这样一个简单想法所必需的 我有一个简单的表创建表单,它允许用户从给定的数据集中提取某些列: class TableBuildingForm(forms.Form): data_set = forms.ChoiceField(choices=DATASETS,required=True,label="Initial object") col1 = forms.CharField(label='Column 1', max_leng

警告:我知道Fieldset,但仍然不相信它们是实现这样一个简单想法所必需的

我有一个简单的表创建表单,它允许用户从给定的数据集中提取某些列:

class TableBuildingForm(forms.Form):
    data_set = forms.ChoiceField(choices=DATASETS,required=True,label="Initial object")
    col1 = forms.CharField(label='Column 1', max_length=100, required=False)
    col2 = forms.CharField(label='Column 2', max_length=100, required=False)
    col3 = forms.CharField(label='Column 3', max_length=100, required=False)
    col4 = forms.CharField(label='Column 4', max_length=100, required=False)
    col5 = forms.CharField(label='Column 5', max_length=100, required=False)
    sort_by = forms.CharField(label='Sort by', max_length=100, required=False)
然后,在处理视图时,我会执行以下操作:

def custom_table(request):
    # if this is a POST request we need to process the form data
    rows = []
    columns = []

    if request.method == 'POST':
      form = forms.TableBuildingForm(request.POST)
      if form.is_valid():
        sort_by = form.cleaned_data['sort_by']
        columns = [ col for col in [
                    form.cleaned_data['col1'],
                    form.cleaned_data['col2'],
                    ... etc ...
                  ]
忽略动态表单的前端方面(这并不困难),直接的问题是如果用户想要超过5列,比如6列、9列或42列,该怎么办

好吧,我看到的每一个答案都暗示着形式。但是对于这个用例来说,这意味着用一个字段创建表单-
col1
,这看起来太复杂了

我想要的是:

class TableBuildingForm(forms.Form):
    data_set = forms.ChoiceField(choices=DATASETS,required=True,label="Initial object")
    columns = forms.CharField(label='Column 1', max_length=100, required=False)
    sort_by = forms.CharField(label='Sort by', max_length=100, required=False)
与相应的:

def custom_table(request):
    # if this is a POST request we need to process the form data
    rows = []
    columns = []

    if request.method == 'POST':
      form = forms.TableBuildingForm(request.POST)
      if form.is_valid():
        sort_by = form.cleaned_data['sort_by']
        columns = form.cleaned_data['columns']
是否有一种简单的方法可以声明一个字段可以在django表单*中重复,或者如果不是这样,是否有一种方法可以捕获所有返回的数据预清理/验证以获取所有列


*我不希望django为我构建前端,我可以做到。我只是在寻找一种方法,让django在返回多个字段时不会抛出投诉

是的,还有一种方法可以做到这一点

不要像这样声明所有字段-

class TableBuildingForm(forms.Form):
    data_set = forms.ChoiceField(choices=DATASETS,required=True,label="Initial object")
    col1 = forms.CharField(label='Column 1', max_length=100, required=False)
    col2 = forms.CharField(label='Column 2', max_length=100, required=False)
    col3 = forms.CharField(label='Column 3', max_length=100, required=False)
    col4 = forms.CharField(label='Column 4', max_length=100, required=False)
    col5 = forms.CharField(label='Column 5', max_length=100, required=False)
    sort_by = forms.CharField(label='Sort by', max_length=100, required=False)
在表单的
\uuuu init\uuu
方法中声明所有表单字段。因为在中为GET和POST创建表单时,会调用
\uu ini\uu
。因此,当HTTP post中的值绑定完成时,将填充所有动态字段并正确绑定-

class TableBuildingForm(forms.Form):
    data_set = forms.ChoiceField(choices=DATASETS,required=True,label="Initial object")            
    sort_by = forms.CharField(label='Sort by', max_length=100, required=False)

    def __init__(self, data=None, files=None, instance=None, **kwargs):
        super().__init__(data=data, files=files, instance=instance, **kwargs)

        for x in xrange(10): # just a dummy for 10 values
            self.fields['col' + str(x)] = forms.CharField(label='Column ' + str(x), max_length=100, required=False)
然后,在clean方法中,您可以获得值-

def clean(self):
    value = self.cleaned_data['field_' + str(0)]
这就是我填充具有动态元字段的表单的方式

编辑:如果字段添加了JS

要处理此问题,请保留另一个字段名
count

class TableBuildingForm(forms.Form):
        data_set = forms.ChoiceField(choices=DATASETS,required=True,label="Initial object")            
        sort_by = forms.CharField(label='Sort by', max_length=100, required=False)
        count = forms.HiddenField(required=False)
然后用JS更新值的计数。比如说5

然后更新您的<代码> init <代码>,考虑这个值-< /p>

    def __init__(self, data=None, files=None, instance=None, **kwargs):
        super().__init__(data=data, files=files, instance=instance, **kwargs)
        _count = int(self.cleaned_data['count'])
        for x in xrange(_count ): # get values from count because it will be updated with js
            self.fields['col' + str(x)] = forms.CharField(label='Column ' + str(x), max_length=100, required=False)

你的后端数据库是什么?我想我的建议是,使用一个类似于逗号分隔列表的东西,在
clean
方法中对单个元素进行验证,元信息可以作为kwarg发送到表单类中。后端是无关的吗?我不是在构建一个模型表单,只是一个带有重复字符域的常规表单。事实上,你是对的。我正在考虑持久存储,请看一看,但对于动态项目计数没有现成的解决方案。@kmmbvnr这是我必须采取的路线。我将很快发布该方法,并将其作为django multicharfield或类似的内容放在github上。如果我使用javascript添加第11个字段,这会处理它吗?