Django 表单 - 带下拉框的复选框组

1 投票
3 回答
2074 浏览
提问于 2025-04-28 02:53

有人能告诉我怎么用Django表单写一个带下拉框的复选框组的自定义小部件/自定义字段吗?

  1. 所有的复选框应该有相同的名字(复选框组)
  2. 每个复选框下面应该有一个下拉框(所有复选框用的是同一个下拉框)
  3. 自定义小部件/自定义字段应该接受一个参数options=[],用来生成复选框组
  4. 复选框组需要有必填验证(required=True)

在这里输入图片描述

举个例子:文本框会显示尺寸,每个尺寸下面应该有一个下拉框,里面列出一些聚合函数。

暂无标签

3 个回答

0

如果我理解得没错,这样做就可以了。

根据你在视图中有什么内容,只需将一些列表放入你的列表中作为上下文。根据列表中有多少个项目,它会为每个项目创建一个复选框列表的组合。

{% for number in your_list %}
    <div class="check_box" id="check_box_{{ number }}">
        <input id="cb_{{ number }}" name="cb_{{ number }}" type="checkbox"><label for="cb_{{ number }}">textbox {{ number }}</label>
        <select class="some_class">
            <option value="1">Sum</option>
            <option value="2">Difference</option>
            <option value="3">Whatever</option>
        </select>
    </div>
{% endfor %}

输出结果看起来会像这样: http://jsfiddle.net/3vetooLp/1/

1

我会使用 MultiValueFieldMultiWidget

你可以让 MultiValueField 的 init 方法接受你想要的任何选项,这样就可以构建所有的选项。同时,在 MultiWidget 中使用自定义逻辑来显示所有的复选框和下拉框,并将用户输入的值进行压缩或解压缩,变成合适的格式,比如一个字典 {复选框名称: 操作}。

0

在 forms.py 文件中

class DynamicForm(forms.Form):

    options = [
    ('Textbox1', 'Textbox1'),
    ('Textbox2', 'Textbox2'),
    ...
    ]

    dynamic_data = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=options)

    def __init__(self, *args, **kwargs):
        super(DynamicForm, self).__init__(*args, **kwargs)

        for i in range(1,len(self.options)+1):
            self.fields['dd_func_'+str(i)] = forms.ChoiceField(widget=forms.Select, choices= [
                            ('average', 'average'),
                            ('sum', 'sum')], initial='sum', required=False)

    def __getitem__(self, name):
        try:
            field = self.fields[name]
        except KeyError:
            raise KeyError('Key %r not found in Form' % name)
        return forms.forms.BoundField(self, field, name)

在 views.py 文件中

from app.forms import DynamicForm

def create_form(request):
    if request.method == 'POST':
        dynamic_form = DynamicForm(request.POST)
        ...
        ...
    else:
        dynamic_form = DynamicForm()
    return render(request, 'form.html', {
        'dynamic_form': dynamic_form
        })

在 templates/form.html 文件中

{% load myfilters %}
{{ dynamic_form.dynamic_data.errors }}
{% for checkbox in dynamic_form.dynamic_data|checkboxiterator %} 
    {{ checkbox }}
    {% with c=forloop.counter|stringformat:"s" %}
        {% with c='dd_func_'|add:c %}
            {{ dynamic_form|lookup:c }}
        {% endwith %}
    {% endwith %}
{% endfor %}

在 templatetags/myfilters.py 文件中

https://djangosnippets.org/snippets/2159/

还有

@register.filter
def lookup(f, name):
    try:        
    return f[name]
    except KeyError:
    return None

撰写回答