0

I have a django model named archive that is tied to a group (django auth) by a foreign key. In order for a user to edit something in this archive, they must have permission to do so through django-guardian. I can link an archive with a group as shown in my code below, however, I need to be able to set per-object (archive)-permissions with each group as well. I am seeking to do this using a post_save or post_delete signal (to properly prevent orphan permissions).

In other words, here are the steps I want to accomplish. Visit Admin page. Create/Edit an instance of Archive. Specify on that page what user-group will be associated with that particular Archive. Upon saving that instance, Django should automatically authenticate the specified group with 'read' permissions for that instance of Archive.

What file would I store Archive_post_save_handler in? models.py? As it stands, I can't assign group permissions because I think I am having trouble passing objects through my functions. How can I accomplish this? As a bonus question, will this hook also apply if I edited the model through a shell?

models.py

from django.db import models
from django.contrib.auth.models import Group
from django.db.models.signals import *
from django.dispatch import receiver

class Archive(models.Model):
    name = models.CharField(max_length = 30)
    nickname = models.CharField(max_length = 30, blank=True)
    Group = models.ForeignKey(Group, blank=True, null=True, help_text='A group of users that are allowed access to the archive. This should typically be called the same thing as the archive name.')

    class Meta:
        permissions = (
            ('read', 'Read Archive'),
        )

    def __unicode__(self):
        return self.name

@receiver(post_save, sender=Archive)
def Archive_post_save_handler(sender, instance, **kwarks):
    group = Group.objects.get(name=instance.Group)
    assign_perm('read', group, instance) #what I primarily want to accomplish in this question is on this line
mh00h
  • 1,824
  • 3
  • 25
  • 45
  • my problem seems to resolve around the phrase `archive` at `assign_perm('read', group, archive)`. I don't think I have the right variable there. – mh00h Aug 12 '13 at 04:28

1 Answers1

2

I think the code you pasted here will cause a recursive calling Archive_post_save_handler, because the last line of code will also trigger another post_save signal. You should get the created argument from the kwargs to test if the instance is created for the first time.

toozoofoo
  • 36
  • 1
  • Hmm... interesting. I do get an error: `maximum recursion depth exceeded in cmp`. I still need help getting my assign_perm to work as well though if you have any idea; that weighs more heavily with me. I edited the question to reflect that. – mh00h Aug 12 '13 at 04:21
  • 1
    Well, the signal will trigger from django admin or django shell. As to your problem, 1. Have you assigned users to the `group` instance? 2. `group = Group.objects.get(name=instance.Group)`, why not just `group = instance.Group` – toozoofoo Aug 12 '13 at 05:36
  • Users are assigned to the group instance. I'm getting a `does not exist error:` `Permission matching query does not exist. Lookup parameters were {'codename': u'read', 'content_type': }`. Is there something else that belongs in place of the last `instance` of my code? – mh00h Aug 12 '13 at 05:46
  • nevermind: got it. http://stackoverflow.com/questions/18117687/django-south-and-guardian-migrate. Thanks for the help. – mh00h Aug 12 '13 at 05:53
  • 1
    The error tells that there is no permission record of `read` in the db. If the code bellow is added after `./manage.py syncdb`, there will be the problem. ` class Meta: permissions = ( ('read', 'Read Archive'), ) ` You should insert a row in table `auth_permission` or drop the Archive table and run `./manage.py syncdb`. – toozoofoo Aug 12 '13 at 05:58