我需要有关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('')
答案 0 :(得分:24)
具有相同名称的多个复选框都是相同的字段。
<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()
答案 1 :(得分:5)
我不能评论Thomas解决方案,所以我在这里做。
对于ModelMultipleChoiceField,参数名称不是选项,而是查询集。
所以采取最后一个例子:
class UnknownForm(forms.Form):
choices = forms.ModelMultipleChoiceField(
choices = queryset_of_valid_choices, # not optional, use .all() if unsure
widget = forms.CheckboxSelectMultiple,
)
答案 2 :(得分: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
答案 3 :(得分:0)
我发现这在向用户添加组或权限时非常有用。
确保您在页面视图中包含默认的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
如果没有选择任何组,这可能仍然需要一些逻辑,但应该足以开始。