Mortiz, have you taken a look at django-guardian, it has been out as long as object level hooks have been implemented; I have been using it successfully since version 0.2 which is about 2 years now.
Your need to add ‘object_permissions’ to a model is an incorrect approach in my opinion as it would require any old apps to undergo a schema migration. Your generic relations concerns might be valid however I would like to mention Django guardian does use generic FK but so does built in django auth – so I think this approach is just fine. In the end I would humbly suggest that rather then creating a competing solution you instead contribute your skills and suggestions to an already working project. From: Moritz S. Sent: Friday, April 13, 2012 7:56 PM To: django-developers@googlegroups.com Subject: Implementation of Object Permissions Hi all, I have been using django for a while and became happy by the time I discovered the auth module that supports permission handling. But this module turned out to only be able to handle model based permissions. I could not imagine django of not having such a basic functionality (in my opinion) despite of having so much other great abilities. So I started to search for it but eventually figured out that the auth model's code was prepared for implementing this but it haven't been done yet. So I decided to write a patch for this on my own. Currently I'm writing this patch but there are several design decisions to make so I wanted to share this with you and hear your opinions. First of all: I think the main problem of this implementation is to link the objects with the corresponding permissions. With model based permissions that's easy because you only have to store a permission once with the models ContentType and relate with a ManyToManyField to them and that's it. The problem with object based permissions is that every object needs to have his own set of permissions and you can't just use ForeignKeys or ManyToManyFields from a permission model because in the process of creating the permission model (and table) you don't know about the models that will provide object permissions therefore you can't refer to them. So I tried some different implementations. At first I tried to used dynamic models (e.g. this project makes use of them: http://pypi.python.org/pypi/django-object-permissions): The idea is to create intermediate models like 'MyModel_ObjectPermissions' that stores the object permissions with foreign keys to the model itself, user and group. But this has a huge disadvantage: the use of dynamic models. In fact thinking as database specialist that is the easiest way of connecting the model instances to the permissions but dynamic models are very sensitive and kind of hacky in my opinion and I think that does not match well with django's ideas. Then I found out about GenericRelations from the contenttypes framework. So you could possibly use a single model called 'ObjectPermissions' or something and link users, permissions and instances of all types of models and only had to use one GenericRelation. This solution eliminates the problem wit the dynamic models because it doesn't even make use of them. But the GenericRelations have another not negligible disadvantage: The databases behind django don't have native support for them. I thought of huge django projects handling thousands and thousands of object permissions. I think these GenericRelations wouldn't be such scalable to make use of them. The only solution for me was to find a way to link the (unknown) model instances to the permissions in the reversed direction. So not use ForeignKeys, etc. in the permission model to refer to the unknown model but to refer from the model to the permission itself. That would fix the problem of not knowing the models while creating the permission model. So in the end I thought of following: - there is a new model in the auth module called 'ObjectPermission' this model has ManyToManyFields to User and Group and a ForeignKey to Permission - instead of ObjectPermission referring to the model using object permissions, a field called 'object_permissions' is added to the corresponding models (by use of the class_prepared signal) (dynamically adding fields is way better than use completely dynamic models in my opinion) - the object_permissions field is a ManyToManyField, that refers to ObjectPermission. In fact, a 'ManyToOneField' would be sufficient but django only has one to many fields (the ForeignKeyField) and we can't just use this in the reversed direction, as I mentioned above This picture illustrates the relations: Furthermore I thought of slightly modifying the auth module (apart from the ObjectPermission model) in the following way: - when the auth app is initialized a function is registered to listen to the class_prepared signal. This function adds the object_permissions field to each model, that has the Meta.object_permissions set to True (for this to work, this meta attribute has to be set in django.db.models.options) - the User model gets the methods grant_perm and revoke_perm that takes the permission and as optional argument the object in order to simplify the process of handling permissions - in the ModelBackend the methods has_perm, etc. have to be modified to be able to handle function calls with given objects (obviously) So that was the technical part. Now I want you to give feedback if this implementation is viable and maybe sometimes may get into django. Thanks, Moritz -- You received this message because you are subscribed to the Google Groups "Django developers" group. To view this discussion on the web visit https://groups.google.com/d/msg/django-developers/-/WbQ6EMVuxqkJ. To post to this group, send email to django-developers@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en. Daniel Sokolowski Danols Web Engineering http://webdesign.danols.com/ Kingston, ON K7L 1H3, Canada Notice of Confidentiality: The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review re-transmission dissemination or other use of or taking of any action in reliance upon this information by persons or entities other than the intended recipient is prohibited. If you received this in error please contact the sender immediately by return electronic transmission and then immediately delete this transmission including all attachments without copying distributing or disclosing same. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To post to this group, send email to django-developers@googlegroups.com. To unsubscribe from this group, send email to django-developers+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-developers?hl=en.