Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django-guardian - where to assign default permission on object creation

I am starting an app that has a complex permission structure that will inevitably be managed by the users themselves. I have the following permissions in the model:

class Meta:
    permissions = (
    ('can_view', 'View project'),
    ('manage_view', 'Can assign View project'),
    ('can_edit', 'Edit project'),
    ('manage_edit', 'Can assign Edit project'),
    ('can_delete', 'Delete project'),
    ('manage_delete', 'Can assign Delete project'),
    ('creator', 'Full access to model features.'),
    )

These will be managed at the object level with Django-guardian and I am using custom mixins to deal with all of the various combinations and features.

The 'creator' permission is assigned to the initial creator of an object, and they can assign the other permissions to Users via an e-mail based invite system.

My question surrounds the options are for assigning the creator permission on creation of the object.

Some approaches I have thought of so far:

Assign in view after save

newObject.save()
assign('creator', User, newObject)

Generally, I prefer to get these types of events out of my views though.

Override save()

The problem with this method is I have to give the save access to the User object, which means also overriding the init to set self.request = request.

post_save signal

I know I could take advantage of this signal, but compared to the previous two I haven't attempted an implementation of this yet.

Hopefully this provides enough insight into where I am at with things.

I would love to know what the best of these methods would be, or, if they are all bad ideas what an alternative implementation might be.

Thanks,

JD

like image 764
jondykeman Avatar asked Oct 26 '12 03:10

jondykeman


1 Answers

AD Override save(): You can add user parameter to save method (so you don't have to override init too). This way code would break at runtime if you try to call save method without passing user instance (and as long as you test your code you should be fine with that approach).

AD post_save signal : If you didn't try it... try it! Documentation is pretty well on the signals topic and they are rather easy to learn. What might be tricky is where should you connect signals probably (I prefer to do that at the end of models module).

Unfortunately, there is no best approach for your answer. Also, remember that neither save method nor post_save signal are not fired if you i.e. insert instances with raw SQL or do bulk_create (https://docs.djangoproject.com/en/stable/ref/models/querysets/#bulk-create). So identify places where you want this automatic permission assignment to be happening (that should be probably one place anyway).

Alternatively, you can add FK field pointing at the creator to your model. You would be able to use that information instead of checking permission with guardian (and as you noted about using mixins that should actually fit your problem well too). I used that approach for my project management application some time ago.

Hope that helps!

https://docs.djangoproject.com/en/stable/ref/models/querysets/#bulk-create

like image 155
lukaszb Avatar answered Oct 09 '22 10:10

lukaszb