kpsul/kfet/auth/fields.py
Aurélien Delobelle 2c76bea1e6 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.
2017-10-17 16:50:39 +02:00

78 lines
2.6 KiB
Python

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):
kwargs.setdefault('queryset', Group.objects.all())
kwargs.setdefault('widget', forms.CheckboxSelectMultiple)
super().__init__(**kwargs)
class BasePermissionsField(forms.ModelMultipleChoiceField):
def __init__(self, **kwargs):
kwargs.setdefault('widget', forms.CheckboxSelectMultiple(attrs={
'field_class': 'permissions-field',
}))
super().__init__(**kwargs)
# 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):
def __init__(self, **kwargs):
kwargs.setdefault('queryset', Permission.kfetcore.all())
super().__init__(**kwargs)