Python/Django 带有 OptGroup 选项的 MultipleChoiceField
Python/Django MultipleChoiceField with OptGroup Options
我在弄清楚如何使用 MutlipleChoiceField
select 选项在我的 Django 表单中配置 optgroup
标签时遇到了一些麻烦。
基本上我已经创建了一个界面,它使用 Ajax 来允许允许或删除我的项目的权限,并且我使用一个表单来预填充 2 MutlipleChoiceField
中已授予和未授予的权限 select盒。
该项目目前大约有 190 个权限,因此 select 框目前看起来非常庞大,我想要的是使用 optgroup
html 标记对这些选项进行分组.如果我静态输入表单的选项,我理解它是如何工作的,但目前使用我当前的代码,我看不到一种方法可以轻松地将它们按 app_label
分组以添加正确的 optgroup
。有人可以帮我吗?
这是我的代码:
from django import forms
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
class GroupForm(forms.ModelForm):
class Meta:
model = Group
fields = ['permissions']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if 'instance' in kwargs:
instance = kwargs['instance']
granted_permissions = list()
not_granted_permissions = list()
all_permissions = Permission.objects.all().order_by('id', 'content_type__app_label')
for permission in all_permissions:
if permission in instance.permissions.all().order_by('id', 'content_type__app_label'):
# I NEED OPTGROUP HERE FOR EACH ITEMS content_type__app_label
granted_permissions.append([permission.id, permission.name])
else:
# I NEED OPTGROUP HERE FOR EACH ITEMS content_type__app_label
not_granted_permissions.append([permission.id, permission.name])
self.fields['permissions'] = forms.MultipleChoiceField(
label='Granted Permissions',
required=False,
choices=granted_permissions)
self.fields['not_granted_permissions'] = forms.MultipleChoiceField(
label='Not Granted Permissions',
required=False,
choices=not_granted_permissions)
我最终以这种方式完成了问题,现在一切正常,optgroups
有效:.
from django import forms
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
class GroupForm(forms.ModelForm):
class Meta:
model = Group
fields = ['permissions']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if 'instance' in kwargs:
instance = kwargs['instance']
all_permissions = Permission.objects.exclude(
Q(content_type=ContentType.objects.get(app_label='contenttypes', model='contenttype')) |
Q(content_type=ContentType.objects.get(app_label='sessions', model='session')) |
Q(codename='add_group') |
Q(codename='delete_group') |
Q(codename='add_permission') |
Q(codename='delete_permission') |
Q(codename='change_permission')
).order_by('id', 'content_type__app_label')
granted_builder = dict()
not_granted_builder = dict()
for permission in all_permissions:
if permission in instance.permissions.all().order_by('id', 'content_type__app_label'):
if not granted_builder.get(permission.content_type.app_label):
granted_builder[permission.content_type.app_label] = [[permission.id, permission.name]]
else:
# we have a list, so append the permission to it
granted_builder[permission.content_type.app_label].append([permission.id, permission.name])
else:
if not not_granted_builder.get(permission.content_type.app_label):
not_granted_builder[permission.content_type.app_label] = [[permission.id, permission.name]]
else:
# we have a list, so append the permission to it
not_granted_builder[permission.content_type.app_label].append([permission.id, permission.name])
# loop through granted permissions
final_granted_permissions = list()
for app_label, list_of_options in granted_builder.items():
# [optgroup, [options]]
final_granted_permissions.append([app_label.title(), list_of_options])
# loop through not granted permissions
final_not_granted_permissions = list()
for app_label, list_of_options in not_granted_builder.items():
# [optgroup, [options]]
final_not_granted_permissions.append([app_label.title(), list_of_options])
self.fields['group_name'] = forms.CharField(
required=False,
widget=forms.HiddenInput(attrs={'value': instance.name}))
self.fields['permissions'] = forms.MultipleChoiceField(
label='Granted Permissions',
required=False,
choices=final_granted_permissions)
self.fields['not_granted_permissions'] = forms.MultipleChoiceField(
label='Not Granted Permissions',
required=False,
choices=final_not_granted_permissions)
我在弄清楚如何使用 MutlipleChoiceField
select 选项在我的 Django 表单中配置 optgroup
标签时遇到了一些麻烦。
基本上我已经创建了一个界面,它使用 Ajax 来允许允许或删除我的项目的权限,并且我使用一个表单来预填充 2 MutlipleChoiceField
中已授予和未授予的权限 select盒。
该项目目前大约有 190 个权限,因此 select 框目前看起来非常庞大,我想要的是使用 optgroup
html 标记对这些选项进行分组.如果我静态输入表单的选项,我理解它是如何工作的,但目前使用我当前的代码,我看不到一种方法可以轻松地将它们按 app_label
分组以添加正确的 optgroup
。有人可以帮我吗?
这是我的代码:
from django import forms
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
class GroupForm(forms.ModelForm):
class Meta:
model = Group
fields = ['permissions']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if 'instance' in kwargs:
instance = kwargs['instance']
granted_permissions = list()
not_granted_permissions = list()
all_permissions = Permission.objects.all().order_by('id', 'content_type__app_label')
for permission in all_permissions:
if permission in instance.permissions.all().order_by('id', 'content_type__app_label'):
# I NEED OPTGROUP HERE FOR EACH ITEMS content_type__app_label
granted_permissions.append([permission.id, permission.name])
else:
# I NEED OPTGROUP HERE FOR EACH ITEMS content_type__app_label
not_granted_permissions.append([permission.id, permission.name])
self.fields['permissions'] = forms.MultipleChoiceField(
label='Granted Permissions',
required=False,
choices=granted_permissions)
self.fields['not_granted_permissions'] = forms.MultipleChoiceField(
label='Not Granted Permissions',
required=False,
choices=not_granted_permissions)
我最终以这种方式完成了问题,现在一切正常,optgroups
有效:.
from django import forms
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
class GroupForm(forms.ModelForm):
class Meta:
model = Group
fields = ['permissions']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if 'instance' in kwargs:
instance = kwargs['instance']
all_permissions = Permission.objects.exclude(
Q(content_type=ContentType.objects.get(app_label='contenttypes', model='contenttype')) |
Q(content_type=ContentType.objects.get(app_label='sessions', model='session')) |
Q(codename='add_group') |
Q(codename='delete_group') |
Q(codename='add_permission') |
Q(codename='delete_permission') |
Q(codename='change_permission')
).order_by('id', 'content_type__app_label')
granted_builder = dict()
not_granted_builder = dict()
for permission in all_permissions:
if permission in instance.permissions.all().order_by('id', 'content_type__app_label'):
if not granted_builder.get(permission.content_type.app_label):
granted_builder[permission.content_type.app_label] = [[permission.id, permission.name]]
else:
# we have a list, so append the permission to it
granted_builder[permission.content_type.app_label].append([permission.id, permission.name])
else:
if not not_granted_builder.get(permission.content_type.app_label):
not_granted_builder[permission.content_type.app_label] = [[permission.id, permission.name]]
else:
# we have a list, so append the permission to it
not_granted_builder[permission.content_type.app_label].append([permission.id, permission.name])
# loop through granted permissions
final_granted_permissions = list()
for app_label, list_of_options in granted_builder.items():
# [optgroup, [options]]
final_granted_permissions.append([app_label.title(), list_of_options])
# loop through not granted permissions
final_not_granted_permissions = list()
for app_label, list_of_options in not_granted_builder.items():
# [optgroup, [options]]
final_not_granted_permissions.append([app_label.title(), list_of_options])
self.fields['group_name'] = forms.CharField(
required=False,
widget=forms.HiddenInput(attrs={'value': instance.name}))
self.fields['permissions'] = forms.MultipleChoiceField(
label='Granted Permissions',
required=False,
choices=final_granted_permissions)
self.fields['not_granted_permissions'] = forms.MultipleChoiceField(
label='Not Granted Permissions',
required=False,
choices=final_not_granted_permissions)