Skip to content

Commit 660b34a

Browse files
committed
Ensured forum admin forms can be lazily loaded
Forms used by the forum admin classes are now imported using get_class so that it should be possible to easily customize form fields and widgets by relying on the class loading mechanisms provided by django-machina.
1 parent 3c7f79f commit 660b34a

File tree

2 files changed

+119
-94
lines changed

2 files changed

+119
-94
lines changed

machina/apps/forum/admin.py

Lines changed: 11 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,9 @@
88

99
from collections import OrderedDict
1010

11-
from django import forms
1211
from django.conf.urls import url
1312
from django.contrib import admin
1413
from django.contrib.admin import helpers
15-
from django.contrib.admin.widgets import ForeignKeyRawIdWidget
1614
from django.contrib.auth import get_user_model
1715
from django.contrib.auth.models import Group
1816
from django.forms.forms import NON_FIELD_ERRORS
@@ -23,7 +21,6 @@
2321
from django.urls import reverse
2422
from django.utils.translation import ugettext_lazy as _
2523
from mptt.exceptions import InvalidMove
26-
from mptt.forms import TreeNodeChoiceField
2724

2825
from machina.core.db.models import get_model
2926
from machina.core.loading import get_class
@@ -36,11 +33,12 @@
3633
GroupForumPermission = get_model('forum_permission', 'GroupForumPermission')
3734
UserForumPermission = get_model('forum_permission', 'UserForumPermission')
3835

39-
PermissionConfig = get_class('forum_permission.defaults', 'PermissionConfig')
36+
PermissionsForm = get_class('forum.forms', 'PermissionsForm')
37+
PickForumForm = get_class('forum.forms', 'PickForumForm')
38+
PickGroupForm = get_class('forum.forms', 'PickGroupForm')
39+
PickUserForm = get_class('forum.forms', 'PickUserForm')
4040

41-
PERM_GRANTED = 'granted'
42-
PERM_NOT_GRANTED = 'not-granted'
43-
PERM_NOT_SET = 'not-set'
41+
PermissionConfig = get_class('forum_permission.defaults', 'PermissionConfig')
4442

4543

4644
class ForumAdmin(admin.ModelAdmin):
@@ -327,11 +325,11 @@ def _get_permissions_form(self, request, permission_model, filter_kwargs):
327325
permissions_dict = OrderedDict()
328326
for p in editable_permissions:
329327
if p.codename in granted_permissions:
330-
perm_state = PERM_GRANTED
328+
perm_state = PermissionsForm.PERM_GRANTED
331329
elif p.codename in non_granted_permissions:
332-
perm_state = PERM_NOT_GRANTED
330+
perm_state = PermissionsForm.PERM_NOT_GRANTED
333331
else:
334-
perm_state = PERM_NOT_SET
332+
perm_state = PermissionsForm.PERM_NOT_SET
335333
permissions_dict[p.codename] = (p, perm_state)
336334

337335
if request.method == 'POST':
@@ -343,17 +341,17 @@ def _get_permissions_form(self, request, permission_model, filter_kwargs):
343341
permission=permissions_dict[codename][0], **filter_kwargs
344342
)
345343
except permission_model.DoesNotExist:
346-
if value == PERM_NOT_SET:
344+
if value == PermissionsForm.PERM_NOT_SET:
347345
continue
348346
perm = permission_model.objects.create(
349347
permission=permissions_dict[codename][0], **filter_kwargs
350348
)
351349

352-
if value == PERM_NOT_SET:
350+
if value == PermissionsForm.PERM_NOT_SET:
353351
perm.delete()
354352
continue
355353

356-
perm.has_perm = (value == PERM_GRANTED)
354+
perm.has_perm = (value == PermissionsForm.PERM_GRANTED)
357355
perm.save()
358356

359357
self.message_user(request, _('Permissions successfully applied'))
@@ -395,85 +393,4 @@ def _copy_forum_permissions(self, forum_from, forum_to):
395393
new_perm.save()
396394

397395

398-
class PickUserForm(forms.Form):
399-
""" Form allowing to pick a user to edit their permissions. """
400-
401-
user = UserForumPermission._meta.get_field('user').formfield()
402-
anonymous_user = forms.BooleanField(
403-
label=_('Anonymous'),
404-
initial=False,
405-
help_text=_(
406-
'Please select this option if you want to edit the permissions of the anonymous user'
407-
),
408-
)
409-
410-
def __init__(self, *args, **kwargs):
411-
admin_site = kwargs.pop('admin_site')
412-
super().__init__(*args, **kwargs)
413-
414-
self.fields['user'].required = False
415-
self.fields['user'].widget = ForeignKeyRawIdWidget(
416-
UserForumPermission._meta.get_field('user').remote_field, admin_site,
417-
)
418-
419-
self.fields['anonymous_user'].required = False
420-
421-
def clean(self):
422-
cleaned_data = super().clean()
423-
user = cleaned_data.get('user', None)
424-
anonymous_user = cleaned_data.get('anonymous_user', None)
425-
if user and anonymous_user:
426-
self._errors[NON_FIELD_ERRORS] = self.error_class(
427-
[_('Choose either a user ID or select the anonymous user'), ],
428-
)
429-
return cleaned_data
430-
431-
432-
class PickGroupForm(forms.Form):
433-
""" Form allowing to pick a group to edit its permissions. """
434-
435-
group = GroupForumPermission._meta.get_field('group').formfield()
436-
437-
def __init__(self, *args, **kwargs):
438-
admin_site = kwargs.pop('admin_site')
439-
super().__init__(*args, **kwargs)
440-
441-
self.fields['group'].required = False
442-
self.fields['group'].widget = ForeignKeyRawIdWidget(
443-
GroupForumPermission._meta.get_field('group').remote_field, admin_site,
444-
)
445-
446-
447-
class PickForumForm(forms.Form):
448-
""" Form allowing to pick a specific forum. """
449-
450-
forum = TreeNodeChoiceField(queryset=Forum.objects.all(), required=False)
451-
452-
453-
class PermissionsForm(forms.Form):
454-
""" Form allowing to edit permissions. """
455-
456-
def __init__(self, *args, **kwargs):
457-
self.permissions_dict = kwargs.pop('permissions_dict', {})
458-
super().__init__(*args, **kwargs)
459-
460-
# Initializes permission fields
461-
f_choices = (
462-
(PERM_NOT_SET, _('Not set')),
463-
(PERM_GRANTED, _('Granted')),
464-
(PERM_NOT_GRANTED, _('Not granted')),
465-
)
466-
for scope in PermissionConfig.scopes:
467-
codenames = [
468-
x['fields']['codename'] for x in PermissionConfig.permissions if x['scope'] == scope
469-
]
470-
permissions = filter(lambda v: v[0] in codenames, self.permissions_dict.items())
471-
for codename, p in permissions:
472-
self.fields[codename] = forms.ChoiceField(
473-
label=p[0].name, choices=f_choices, required=False, widget=forms.RadioSelect,
474-
)
475-
self.fields[codename].initial = p[1]
476-
self.fields[codename].scope = scope
477-
478-
479396
admin.site.register(Forum, ForumAdmin)

machina/apps/forum/forms.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
"""
2+
Forum forms
3+
===========
4+
5+
This module defines forms provided by the ``forum`` application.
6+
7+
"""
8+
9+
from django import forms
10+
from django.contrib.admin.widgets import ForeignKeyRawIdWidget
11+
from django.forms.forms import NON_FIELD_ERRORS
12+
from django.utils.translation import ugettext_lazy as _
13+
from mptt.forms import TreeNodeChoiceField
14+
15+
from machina.core.db.models import get_model
16+
from machina.core.loading import get_class
17+
18+
19+
Forum = get_model('forum', 'Forum')
20+
GroupForumPermission = get_model('forum_permission', 'GroupForumPermission')
21+
UserForumPermission = get_model('forum_permission', 'UserForumPermission')
22+
23+
PermissionConfig = get_class('forum_permission.defaults', 'PermissionConfig')
24+
25+
26+
class PickUserForm(forms.Form):
27+
""" Form allowing to pick a user to edit their permissions. """
28+
29+
user = UserForumPermission._meta.get_field('user').formfield()
30+
anonymous_user = forms.BooleanField(
31+
label=_('Anonymous'),
32+
initial=False,
33+
help_text=_(
34+
'Please select this option if you want to edit the permissions of the anonymous user'
35+
),
36+
)
37+
38+
def __init__(self, *args, **kwargs):
39+
admin_site = kwargs.pop('admin_site')
40+
super().__init__(*args, **kwargs)
41+
42+
self.fields['user'].required = False
43+
self.fields['user'].widget = ForeignKeyRawIdWidget(
44+
UserForumPermission._meta.get_field('user').remote_field, admin_site,
45+
)
46+
47+
self.fields['anonymous_user'].required = False
48+
49+
def clean(self):
50+
cleaned_data = super().clean()
51+
user = cleaned_data.get('user', None)
52+
anonymous_user = cleaned_data.get('anonymous_user', None)
53+
if user and anonymous_user:
54+
self._errors[NON_FIELD_ERRORS] = self.error_class(
55+
[_('Choose either a user ID or select the anonymous user'), ],
56+
)
57+
return cleaned_data
58+
59+
60+
class PickGroupForm(forms.Form):
61+
""" Form allowing to pick a group to edit its permissions. """
62+
63+
group = GroupForumPermission._meta.get_field('group').formfield()
64+
65+
def __init__(self, *args, **kwargs):
66+
admin_site = kwargs.pop('admin_site')
67+
super().__init__(*args, **kwargs)
68+
69+
self.fields['group'].required = False
70+
self.fields['group'].widget = ForeignKeyRawIdWidget(
71+
GroupForumPermission._meta.get_field('group').remote_field, admin_site,
72+
)
73+
74+
75+
class PickForumForm(forms.Form):
76+
""" Form allowing to pick a specific forum. """
77+
78+
forum = TreeNodeChoiceField(queryset=Forum.objects.all(), required=False)
79+
80+
81+
class PermissionsForm(forms.Form):
82+
""" Form allowing to edit permissions. """
83+
84+
PERM_GRANTED = 'granted'
85+
PERM_NOT_GRANTED = 'not-granted'
86+
PERM_NOT_SET = 'not-set'
87+
88+
def __init__(self, *args, **kwargs):
89+
self.permissions_dict = kwargs.pop('permissions_dict', {})
90+
super().__init__(*args, **kwargs)
91+
92+
# Initializes permission fields
93+
f_choices = (
94+
(self.PERM_NOT_SET, _('Not set')),
95+
(self.PERM_GRANTED, _('Granted')),
96+
(self.PERM_NOT_GRANTED, _('Not granted')),
97+
)
98+
for scope in PermissionConfig.scopes:
99+
codenames = [
100+
x['fields']['codename'] for x in PermissionConfig.permissions if x['scope'] == scope
101+
]
102+
permissions = filter(lambda v: v[0] in codenames, self.permissions_dict.items())
103+
for codename, p in permissions:
104+
self.fields[codename] = forms.ChoiceField(
105+
label=p[0].name, choices=f_choices, required=False, widget=forms.RadioSelect,
106+
)
107+
self.fields[codename].initial = p[1]
108+
self.fields[codename].scope = scope

0 commit comments

Comments
 (0)