16

我需要有关看起来像 Gmail 收件箱并且有多个操作的表单的帮助。有一个项目列表,我想用表格包装它,因为每个项目在行的前面都有复选框。因此,当用户选择几个项目时,他可以单击具有不同操作的两个按钮,例如删除和标记已读。

<form action="">
    {% for item in object_list %}
    <input type="checkbox" id="item.id">
    {{ item.name }}
    {% endfor %}
    <button type="submit" name="delete">Delete</button>
    <button type="submit" name="mark_read">Mark read</button>
</form>

如果使用,我可以找到用户单击哪个提交按钮,if 'delete' in request.POST但我无法引用任何表单,因为我认为 Django 表单无法用未知数量的字段定义。那么如何处理视图中的选定项目?

if request.method == 'POST':
    form = UnknownForm(request.POST):
    if 'delete' in request.POST:
        'delete selected items'
    if 'mark_read' in erquest.POST:
        'mark selected items as read'
    return HttpResponseRedirect('')
4

4 回答 4

34

多个同名复选框都是同一个字段。

<input type="checkbox" value="{{item.id}}" name="choices">
<input type="checkbox" value="{{item.id}}" name="choices">
<input type="checkbox" value="{{item.id}}" name="choices">

您可以使用单个 django 表单字段收集和聚合它们。

class UnknownForm(forms.Form):
    choices = forms.MultipleChoiceField(
        choices = LIST_OF_VALID_CHOICES, # this is optional
        widget  = forms.CheckboxSelectMultiple,
    )

具体来说,您可以使用 ModelMultipleChoiceField。

class UnknownForm(forms.Form):
    choices = forms.ModelMultipleChoiceField(
        queryset = queryset_of_valid_choices, # not optional, use .all() if unsure
        widget  = forms.CheckboxSelectMultiple,
    )

if request.method == 'POST':
    form = UnknownForm(request.POST):
    if 'delete' in request.POST:
        for item in form.cleaned_data['choices']:
            item.delete()
    if 'mark_read' in request.POST:
        for item in form.cleaned_data['choices']:
            item.read = True; item.save()
于 2013-11-13T08:41:44.823 回答
6

我无法评论托马斯的解决方案,所以我在这里做。

对于 ModelMultipleChoiceField,参数名称不是选择,而是查询集。

所以举最后一个例子:

class UnknownForm(forms.Form):
choices = forms.ModelMultipleChoiceField(
    choices = queryset_of_valid_choices, # not optional, use .all() if unsure
    widget  = forms.CheckboxSelectMultiple,
)
于 2014-03-31T13:32:42.400 回答
5

我在使用类基础视图并遍历 Django HTML 模板中未知大小的列表时遇到了同样的问题。

该解决方案使用“发布”并为我工作。我把它放在这里是因为上述解决方案很有帮助,但并没有为我解决循环问题。

HTML 模板:

<form action="" method="post">
    {% for item in object_list %}
        <input type="checkbox" value="{{item.id}}" name="my_object">
        {{ item.name }}
    {% endfor %}
    <button type="submit" name="delete">Delete</button>
    <button type="submit" name="mark_read">Mark read</button>
</form>

形式:

class MyForm(forms.Form):
    my_object = forms.MultipleChoiceField(
        widget=forms.CheckboxSelectMultiple,
    )

在基于类的视图中,使用 post 函数访问 POST 数据。这将允许访问您选中的项目、上下文和其他表单数据的列表。

看法:

Class MyView(FormView):
    template_name = "myawesometemplate.html"
    form_class = MyForm
...
# add your code here 

    def post(self, request, *args, **kwargs):
        ...
        context = self.get_context_data()
        ...
        if 'delete' in request.POST:
            for item in form.POST.getlist('my_object'):
                # Delete
        if 'mark_read' in request.POST:
            for item in form.POST.getlist('my_object'):
                # Mark as read
于 2017-08-24T16:39:57.107 回答
-1

我发现这在向用户添加组或权限时非常有用。

确保您的页面视图中包含默认的 django 组和权限。

from django.contrib.auth.models import Permission, Group

如果您从数据库表中提取选项,您可以使用带有小部件的 django 表单对象来动态加载所有可用选项。您还需要确保您的表单名称与模型名称相同。

    groups = forms.ModelMultipleChoiceField(label='Groups', required=False, queryset=Group.objects.all(), widget=forms.CheckboxSelectMultiple)
user_permissions = forms.ModelMultipleChoiceField(label='Permissions', required=False, queryset=Permission.objects.all(), widget=forms.CheckboxSelectMultiple)

然后在该页面的视图方法的 post 部分中,您可以获得作为选项对象列表返回的选定选项,并使用 for 循环将它们添加到用户对象。

u.save()  # required to save twice, so this saves the other form fields.
        user.groups.clear()
        u.user_permissions.clear()
        # print('Group name:', form.cleaned_data['groups'])
        for group in form.cleaned_data['groups']:
            print(group)  # Prints to your console for debugging
            user.groups.add(group)
        for permission in form.cleaned_data['user_permissions']:
            print(permission)  # Prints to your console for debugging
            user.user_permissions.add(permission)
        u.save()  #This saves the groups and permissions

如果没有选择任何组,这可能仍然需要一些逻辑,但应该足以开始。

于 2016-02-20T18:48:55.943 回答