Last active
June 25, 2019 14:06
-
-
Save dz0/ca12e1f06754adcaaa38decba67e733e to your computer and use it in GitHub Desktop.
constructed by `GroupObjectsPermission` as example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Experiment form</title> | |
| </head> | |
| <body> | |
| <form action="" method="post"> | |
| {% csrf_token %} | |
| {{ form }} | |
| <input type="submit" value="Submit"> | |
| </form> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ########### choose multiple objects (Bookable) for selected group+permission | |
| from django.contrib.auth.models import Permission | |
| ## guardian/forms.py | |
| from django import forms | |
| from django.utils.translation import ugettext as _ | |
| from guardian.shortcuts import assign_perm, remove_perm, get_objects_for_group | |
| class BasePermissionObjectsForm(forms.Form): | |
| """ | |
| Base form for object permissions management. Needs to be extended for usage | |
| with users and/or groups. | |
| """ | |
| def __init__(self, permission: Permission, model_class=Bookable, *args, **kwargs): | |
| """ | |
| Constructor for BaseObjectPermissionsForm. | |
| :param obj: Any instance which form would use to manage object | |
| permissions" | |
| """ | |
| super().__init__(*args, **kwargs) | |
| self.permission = permission | |
| self.model_class = model_class # TODO: find out from permission codename? | |
| self.field_name = 'objects' # self.get_obj_perms_field_name() | |
| self.fields[self.field_name] = self.get_field() | |
| def get_field_initial(self): | |
| return [] | |
| def get_field(self): | |
| """ | |
| Returns field instance for object permissions management. May be | |
| replaced entirely. | |
| """ | |
| field_class = forms.MultipleChoiceField | |
| field = field_class( | |
| label=_('Objects'), | |
| choices=self.get_field_choices(), | |
| initial=list(self.get_field_initial()), | |
| widget=self.get_field_widget(), | |
| required=False, | |
| ) | |
| return field | |
| def get_obj_perms_field_name(self): | |
| """ | |
| Returns name of the object permissions management field. Default: | |
| ``permission``. | |
| """ | |
| return 'permissions' | |
| def get_queryset(self): | |
| return self.model_class.objects.all().select_related(*self.model_class.__str__.select_related) # TODO: filter by team | |
| def get_field_choices(self): | |
| """ | |
| Returns choices for object permissions management field. Default: | |
| list of tuples ``(codename, name)`` for each ``Permission`` instance | |
| for the managed object. | |
| """ | |
| choices = [(obj.id, str(obj)) for obj in self.get_queryset()] | |
| return choices | |
| def get_field_widget(self): | |
| """ | |
| Returns object permissions management field's widget base class. | |
| Default: ``django.forms.SelectMultiple``. | |
| """ | |
| return forms.CheckboxSelectMultiple | |
| # return forms.SelectMultiple | |
| def save_objects(self): | |
| """ | |
| Must be implemented in concrete form class. This method should store | |
| selected object permissions. | |
| """ | |
| raise NotImplementedError | |
| class GroupPermissionObjectsForm(BasePermissionObjectsForm): | |
| """ | |
| Object level permissions management form for usage with ``Group`` instances. | |
| Example usage:: | |
| from django.shortcuts import get_object_or_404 | |
| from myapp.models import Post | |
| from guardian.forms import GroupObjectPermissionsForm | |
| from guardian.models import Group | |
| def my_view(request, post_slug, group_id): | |
| group = get_object_or_404(Group, id=group_id) | |
| post = get_object_or_404(Post, slug=post_slug) | |
| form = GroupObjectPermissionsForm(group, post, request.POST or None) | |
| if request.method == 'POST' and form.is_valid(): | |
| form.save_obj_perms() | |
| ... | |
| """ | |
| def __init__(self, group, *args, **kwargs): | |
| self.group = group | |
| super().__init__(*args, **kwargs) | |
| def get_field_initial(self): | |
| qs_objects = get_objects_for_group(self.group, self.permission.codename, klass=self.model_class) | |
| return qs_objects.values_list('id', flat=True) | |
| def save_objects(self): | |
| """ | |
| Saves selected object permissions by creating new ones and removing | |
| those which were not selected but already exists. | |
| Should be called *after* form is validated. | |
| """ | |
| qs = self.model_class.objects.all() | |
| selected = set(self.cleaned_data[self.field_name]) | |
| all = set([c[0] for c in self.get_field_choices()]) | |
| initial = set(self.get_field_initial()) | |
| to_remove = (all - selected) & initial | |
| remove_perm(self.permission.codename, self.group, qs.filter(id__in=to_remove)) | |
| to_assign = selected - initial | |
| assign_perm(self.permission.codename, self.group, qs.filter(id__in=to_assign)) | |
| def demo_select_objects(request, group_name='teamX-groupA', permission_name='view_bookable'): | |
| group = get_object_or_404(Group, name=group_name) | |
| permission = get_object_or_404(Permission, codename=permission_name) | |
| form = GroupPermissionObjectsForm(group, permission, request.POST or None) | |
| if request.method == 'POST' and form.is_valid(): | |
| form.save_objects() | |
| return render(request, '_experiment_permissions_form.html', context={'form':form}) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment