Python / Django MultipleChoiceField с параметрами OptGroup - PullRequest
0 голосов
/ 11 июня 2019

У меня возникли небольшие проблемы с выяснением того, как настроить optgroup теги в моей форме Django с помощью MutlipleChoiceField опций выбора.

В основном я создал интерфейс, использующий Ajax для разрешенияили удаление разрешений для моего проекта, и я использую форму для предварительного заполнения предоставленных и не предоставленных разрешений в 2 MutlipleChoiceField полях выбора.

В настоящее время существует около 190 разрешений для проекта, поэтому поле выбора выглядит довольно подавляющимна данный момент я хочу сгруппировать эти параметры, используя тег 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)

1 Ответ

0 голосов
/ 12 июня 2019

Я закончил проблему таким образом, теперь все работает, как ожидалось, и 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)

...