GFK approach is scary, indeed. I've got django-guardian to life during the weekend for some future, rather simple, business apps (aimed to be used within company's intranet). I've made one mistake that is already filed (https://github.com/lukaszb/django-guardian/issues/11). Didn't ever really started working on it, though, as I still feel it's not a long-run solution. Removing Generic Foreign Keys - or at least letting people to easy use FKs instead - is much better one.
However, it should be fairly simply to avoid forcing GFK and I was thinking about this since I first saw some talk by Alex quite long time ago - I believe he's approach at https://github.com/alex/django-taggit is much more desirable for developers (explicit, customizable, providing better performance). By incorporating similar technique django-guardian (and other libraries) could get much better results. The problem is - I don't have much time recently to work on django-guardian (or even give some answer to this thread) so if someone has the energy to contribute, please do! I've also created proper ticket at issue tracker (https://github.com/lukaszb/django-guardian/issues/69) W dniu poniedziałek, 16 kwietnia 2012 21:58:36 UTC+2 użytkownik Daniel Sokolowski napisał: > > 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. <moritz.sich...@googlemail.com> > *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: > > > <https://lh6.googleusercontent.com/-4wiWd_3CYFc/T4i4ZgfPKeI/AAAAAAAAAAM/iCqyCLwKQBA/s1600/object_permissions_models.png> > > > 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 view this discussion on the web visit https://groups.google.com/d/msg/django-developers/-/OCnX8bDQX3oJ. 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.