kpsul/kfet/cms/forms.py

197 lines
6.3 KiB
Python
Raw Normal View History

from django import forms
from django.contrib.auth.models import Group
from django.template.loader import render_to_string
from django.utils.functional import cached_property
from django.utils.translation import ugettext_lazy as _
from wagtail.wagtailusers.forms import GroupPagePermissionFormSet
from utils.forms import KeepUnselectableModelFormMixin
from kfet.auth.fields import BasePermissionsField
from kfet.auth.models import Permission
class CmsGroupForm(KeepUnselectableModelFormMixin, forms.ModelForm):
"""
Allow to change permissions related to the cms of a `Group` object.
"""
access_admin = forms.BooleanField(
label=_("Accès à l'administration"),
required=False,
help_text=_(
"<b>Attention :</b> Aucun paramétrage effectué dans cette section "
"n'aura d'effet si cette case est décochée."
),
)
class Meta:
model = Group
fields = ()
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
group = self.instance
if group.pk is not None:
self.fields['access_admin'].initial = (
group.permissions.filter(pk=self.access_admin_perm.pk).exists()
)
def save(self):
group = super().save()
if self.cleaned_data['access_admin']:
group.permissions.add(self.access_admin_perm)
else:
group.permissions.remove(self.access_admin_perm)
return group
@cached_property
def access_admin_perm(self):
return Permission.objects.get(
content_type__app_label='wagtailadmin',
codename='access_admin',
)
class SnippetsCmsGroupForm(KeepUnselectableModelFormMixin, forms.ModelForm):
permissions = BasePermissionsField(
label='', required=False,
queryset=Permission.kfetcms.all(),
)
keep_unselectable_fields = ['permissions']
class Meta:
model = Group
fields = ('permissions',)
def prepare_page_permissions_formset(pages):
"""
Create a new formset from base `GroupPagePermissionFormSet` Wagtail
formset.
- The choices of `pages` field of forms are limited to `pages`.
- If there is no initial data, add an initial with the first collection
selected.
- Make 'as_admin_panel' use a custom template.
Arguments
pages (iterable of `Page`)
Returns
A formset to select group permissions of pages.
"""
class RestrictedFormSet(GroupPagePermissionFormSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Remove forms cache, as theirs options are changed.
del self.forms
# 'initial' must be setup before accessing 'forms'.
self.initial = list(
filter(lambda i: i['page'] in pages, self.initial))
# This is just little kindness.
if not self.initial and pages:
self.initial = [{'page': pages[0]}]
for form in self.forms:
self.customize_form(form)
@property
def empty_form(self):
form = super().empty_form
self.customize_form(form)
return form
def customize_form(self, form):
# Widget must be setup before queryset.
form.fields['page'].widget = forms.Select()
form.fields['page'].queryset = pages
# Force use of `CheckboxInput` for `DELETE` field, as `HiddenInput`
# is not compatible with `django-formset-js`.
form.fields['DELETE'].widget = forms.CheckboxInput()
def as_admin_panel(self):
# http://docs.wagtail.io/en/latest/reference/hooks.html#register-group-permission-panel
template = 'kfet/permissions/page_permissions_formset.html'
return render_to_string(template, {'formset': self})
return RestrictedFormSet
def prepare_collection_member_permissions_formset(formset_cls, collections):
"""
Create a new formset from base `formset_cls`.
- The choices of `collections` field of forms produced by `formset_cls` are
limited to `collections`.
- If there is no initial data, add an initial with the first collection
selected.
- Make 'as_admin_panel' use a custom template.
Arguments
formset_cls (subclass of
`wagtail.wagtailcore.forms`
`.BaseGroupCollectionMemberPermissionFormSet`
):
Formset to select group permissions of a collection member model.
It should be rerieved from the `group_permission_panel` Wagtail
hook. This includes the `Document` and `Image` models of Wagtail.
collections (iterable of `wagtail.wagtailcore.models.Collection`)
Returns
A formset to select group permissions of collection-related models.
"""
class RestrictedFormSet(formset_cls):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Remove forms cache, as theirs options are changed.
del self.forms
# 'initial' must be setup before accessing 'forms'.
self.initial = list(
filter(lambda i: i['collection'] in collections, self.initial))
# This is just little kindness.
if not self.initial and collections:
self.initial = [{'collection': collections[0]}]
for form in self.forms:
self.customize_form(form)
@property
def empty_form(self):
form = super().empty_form
self.customize_form(form)
return form
def customize_form(self, form):
form.fields['collection'].queryset = collections
# Force use of `CheckboxInput` for `DELETE` field, as `HiddenInput`
# is not compatible with `django-formset-js`.
form.fields['DELETE'].widget = forms.CheckboxInput()
def as_admin_panel(self):
template = (
'kfet/permissions/collection_member_permissions_formset.html')
model = self.permission_queryset[0].content_type.model_class()
return render_to_string(template, {
'formset': self,
'model_name': model._meta.verbose_name_plural,
})
return RestrictedFormSet