Better display of objects of BasePermissionsField
- Permissions are grouped by content type and displayed under its verbose_name_plural. - Default permissions appear before custom ones. - Use `permissions-field` class to enhance display.
This commit is contained in:
parent
07f1a53532
commit
2c76bea1e6
1 changed files with 55 additions and 3 deletions
|
@ -1,7 +1,21 @@
|
|||
import re
|
||||
from itertools import groupby
|
||||
from operator import attrgetter
|
||||
|
||||
from django import forms
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from .models import Group, Permission
|
||||
|
||||
DEFAULT_PERMS = ['view', 'add', 'change', 'delete']
|
||||
|
||||
DEFAULT_PERMS_LABELS = {
|
||||
'view': _("Voir"),
|
||||
'add': _("Ajouter"),
|
||||
'change': _("Modifier"),
|
||||
'delete': _("Supprimer"),
|
||||
}
|
||||
|
||||
|
||||
class GroupsField(forms.ModelMultipleChoiceField):
|
||||
def __init__(self, **kwargs):
|
||||
|
@ -12,11 +26,49 @@ class GroupsField(forms.ModelMultipleChoiceField):
|
|||
|
||||
class BasePermissionsField(forms.ModelMultipleChoiceField):
|
||||
def __init__(self, **kwargs):
|
||||
kwargs.setdefault('widget', forms.CheckboxSelectMultiple)
|
||||
kwargs.setdefault('widget', forms.CheckboxSelectMultiple(attrs={
|
||||
'field_class': 'permissions-field',
|
||||
}))
|
||||
super().__init__(**kwargs)
|
||||
|
||||
def label_from_instance(self, obj):
|
||||
return obj.name
|
||||
# Contain permissions grouped by `ContentType`. Used as choices for
|
||||
# this field.
|
||||
grouped_choices = []
|
||||
|
||||
for ct, perms in groupby(self.queryset, attrgetter('content_type')):
|
||||
model_opts = ct.model_class()._meta
|
||||
choices = []
|
||||
|
||||
# This helps for the default permissions, if they exists, to appear
|
||||
# at the beginning of the permissions list and use custom labels.
|
||||
reg_defaults_p = re.compile(
|
||||
r'^(?P<p_type>({defaults}))_{model_name}$'
|
||||
.format(
|
||||
defaults='|'.join(DEFAULT_PERMS),
|
||||
model_name=model_opts.model_name,
|
||||
)
|
||||
)
|
||||
next_default_pos = 0
|
||||
|
||||
for p in perms:
|
||||
match = reg_defaults_p.match(p.codename)
|
||||
if match:
|
||||
# `p` is a default permission. Use shorter label and insert
|
||||
# after the last default permission seen in `choices`.
|
||||
p_type = match.group('p_type')
|
||||
choices.insert(
|
||||
next_default_pos,
|
||||
(p.id, DEFAULT_PERMS_LABELS[p_type])
|
||||
)
|
||||
next_default_pos += 1
|
||||
else:
|
||||
# Non-default permissions. Use the permission description,
|
||||
# instead of its `__str__`.
|
||||
choices.append((p.id, p.name))
|
||||
|
||||
grouped_choices.append((model_opts.verbose_name_plural, choices))
|
||||
|
||||
self.choices = grouped_choices
|
||||
|
||||
|
||||
class CorePermissionsField(BasePermissionsField):
|
||||
|
|
Loading…
Reference in a new issue