首页 > 解决方案 > Django Crispy Form 类未创建对象

问题描述

我的问题

我正在编写一个 Django 应用程序,我希望用户通过表单输入地址。如果用户想要输入的地址数量超过默认数量 (3),我希望他们能够添加额外的地址字段。我一直在努力弄清楚如何做到这一点。

第一次尝试

我尝试的第一种方法是简单地使用 JavaScript 在单击按钮时添加字段,但是当我这样做时,不会提交来自添加字段的数据。我从硬编码到表单类中的三个字段中获取数据,但没有提交其他字段,我假设因为它们不是我创建的表单类的一部分。

当前尝试

由于我无法使用使用 JavaScript 添加的字段中的数据,因此我现在尝试在 Python 中创建一个动态大小的表单。我的一般想法是将位置字段的数量传递给类,然后使用该数字创建表单。我知道用于创建表单本身的循环机制是有效的,因为我使用硬编码数字对其进行了测试。但是,我在没有覆盖该__init__功能的情况下这样做了。要将数字传递给表单,我需要重写此函数。当我这样做时,似乎没有创建任何表单对象,我不知道为什么。这是我的代码示例:

表格.py

from django import forms
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Submit, Layout, Row, Column, ButtonHolder, Button

class EnterLocationsForm(forms.Form):
    def __init__(self, *args, **kwargs):
        num_locations = kwargs.pop('num_locations')
        super().__init__(*args, **kwargs)

        for i in range(1, num_locations + 1):
            name = 'location{}'.format(i)
            exec("{} = {}".format(
                name,
                "forms.CharField(widget=forms.TextInput(
                                 attrs={'placeholder': 'Address {}'.format(i)}))")
            )
    helper = FormHelper()
    helper.form_class = 'form-horizontal'
    helper.form_method = 'POST'
    helper.form_show_labels = False

    helper.layout = Layout()
    for i in range(1, num_locations + 1):
        helper.layout.append(Row(
            Column('location{}'.format(i), css_class='form-group'),
            css_class='form-row'
            ),)

    helper.layout.append(ButtonHolder(
                 Button('submit', 'Go', css_class='btn btn-primary'),
                 Button('add', '+', css_class="btn btn-success"),
                 css_id="button-row",
             ))

视图.py

from .forms import EnterLocationsForm

location_count = 3

def index(request):
    if request.method == 'POST':
        form = EnterLocationsForm(request.POST, num_locations=location_count)
        ...
    else:
        form = EnterLocationsForm(num_locations=location_count)
        # if I write print(form) here, nothing is printed

    return render(request, 'index.html', {'form': form})

任何关于为什么这不是创建表单对象的提示将不胜感激!如果有办法让我的第一种方法发挥作用,那也很棒。

标签: pythondjangodjango-crispy-forms

解决方案


推荐阅读