Django表单具有未知数量的复选框字段和多个操作

Django表单具有未知数量的复选框字段和多个操作,django,django-models,django-forms,django-templates,django-views,Django,Django Models,Django Forms,Django Templates,Django Views,我需要帮助的形式,看起来像一个Gmail收件箱,并有多个行动。这里有一个项目列表,我想用表单将其包装起来,每个项目的前面都有复选框。因此,当用户选择几个项目时,他可以单击两个按钮,执行不同的操作,例如删除和标记读取 <form action=""> {% for item in object_list %} <input type="checkbox" id="item.id"> {{ item.name }} {% endfor %}

我需要帮助的形式,看起来像一个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>

具有相同名称的多个复选框都位于同一字段中

<input type="checkbox" value="{{item.id}}" name="choices">
<input type="checkbox" value="{{item.id}}" name="choices">
<input type="checkbox" value="{{item.id}}" name="choices">
具体来说,您可以使用ModelMultipleChiceField

类UnknownFormforms。表单: 选项=forms.modelMultipleChiceField queryset=queryset\u有效的\u选项,非可选,使用。如果不确定,则全部使用 widget=forms.CheckboxSelectMultiple, 如果request.method==“POST”: 表单=UnknownFormrequest.POST: 如果request.POST中有“delete”: 对于form.cleaned_数据['choices']中的项: 项目.删除 如果request.POST中有“mark_read”: 对于form.cleaned_数据['choices']中的项: item.read=True;item.save
我不能评论托马斯的解决方案,所以我在这里做

对于ModelMultipleChiceField,参数名称不是choices,而是queryset

最后一个例子:

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

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

确保页面视图中包含默认的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)
然后在该页面的view方法的post部分中,您可以获得作为choice对象列表返回的所选选项,并使用for循环将它们添加到user对象中

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

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

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

此解决方案使用“post”,适合我。我之所以把这个放在这里,是因为上面的解决方案很有帮助,但没有解决我的循环问题

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>
在基于类的视图中,使用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

请原谅我的新手,但它如何知道从哪个模型获取复选框的数据?@dbinott是指它何时显示复选框信息还是在表单提交后?何时显示复选框信息。我正在尝试输出按唱片集分组的歌曲列表,需要能够检查每首歌曲。在类中创建一个名为get_context_dataself的函数,**kwargs。在内部,您可以获取上下文数据并设置复选框要使用的数据。例如,context[checkbox\u list]=self.list\u of\u checkbox\u项然后您可以使用变量“checkbox\u list”在模板中迭代或访问该数据在django文档中有一个很好的解释:@dbinott也要设置模型,您可以在类的顶部使用其他变量初始化:class AuthorDetailFormMixin,DetailView:model=作者表单\u class=作者兴趣表单def获取上下文\u数据。。。
class MyForm(forms.Form):
    my_object = forms.MultipleChoiceField(
        widget=forms.CheckboxSelectMultiple,
    )
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