Skip to content

Instantly share code, notes, and snippets.

@icereval
Last active July 7, 2018 14:37
Show Gist options
  • Save icereval/a035dab53983cf6bfde1ea565d6f2398 to your computer and use it in GitHub Desktop.
Save icereval/a035dab53983cf6bfde1ea565d6f2398 to your computer and use it in GitHub Desktop.
Django Guardian Groups w/ Django ORM's Model Save Events
from django.contrib.auth.models import Group
from django.db import models
from django.db.models.signals import post_save, pre_save
from django.dispatch import receiver
from guardian.shortcuts import assign_perm
class EventModel(models.Model):
class Meta:
abstract = True
def on_pre_save(self):
pass
def on_post_save(self, created):
pass
@receiver(pre_save)
def signal_event_on_pre_save(sender, instance, **kwargs):
if issubclass(sender, EventModel):
instance.on_pre_save()
@receiver(post_save)
def signal_event_on_post_save(sender, instance, created, **kwargs):
if issubclass(sender, EventModel):
instance.on_post_save(created)
class GroupModel(EventModel):
groups = {}
class Meta:
abstract = True
def on_post_save(self, created):
super().on_post_save(created)
if created:
self._make_groups()
def get_group(self, name):
group, _ = Group.objects.get_or_create(name=f'{self._meta.app_label}:{self._meta.model_name}:{self.pk}:{name}')
return group
def remove_from_groups(self, user):
for name in self.groups:
group = self.get_group(name)
user.groups.remove(group)
def _make_groups(self):
for name in self.groups:
group = self.get_group(name)
for perm in self.groups[name]:
assign_perm(perm, group, self)
from django.conf import settings
from django.db import models
from django.utils.translation import ugettext as _
from guardian.models import UserObjectPermissionBase, GroupObjectPermissionBase
from project.models.base import GroupModel
from project.utils.fields import NonNaiveDateTimeField
class OrganizationManager(models.Manager):
def get_by_natural_key(self, name):
return self.get(name=name)
class Organization(GroupModel):
objects = OrganizationManager()
groups = {
'admin': ['view_organization', 'change_organization', 'delete_organization'],
'member': ['view_organization'],
'public': ['view_organization_public'],
}
name = models.TextField(unique=True)
address = models.TextField()
city = models.TextField()
state = models.TextField()
zip_code = models.TextField()
created = NonNaiveDateTimeField(auto_now_add=True)
created_by = models.ForeignKey(
settings.AUTH_USER_MODEL,
db_index=True,
related_name='organizations_created',
on_delete=models.SET_NULL,
null=True,
)
def __str__(self):
return f'{self.name}'
class Meta:
permissions = (
('view_organization', _('Can view organization')),
('view_organization_public', _('Can view organization public')),
)
ordering = ['id']
def on_post_save(self, created):
super().on_post_save(created)
if created:
self.created_by.groups.add(self.get_group('admin'))
class OrganizationUserObjectPermission(UserObjectPermissionBase):
content_object = models.ForeignKey(Organization, on_delete=models.CASCADE)
class OrganizationGroupObjectPermission(GroupObjectPermissionBase):
content_object = models.ForeignKey(Organization, on_delete=models.CASCADE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment