It seems that permission classes are ANDed when REST framework checks permissions. That is every permission class needs to return True for permission to be granted. This makes things like "if you are a superuser, you can access anything, but if you are a regular user you need explicit permissions" a bit hard to implement, you cannot just return False, it will fail the whole stack. Is there a way to maybe short-circuit permissions? Something like "if this permission is granted, stop checking?" or some other way to deal with cases like that?
相关问题
- how to define constructor for Python's new Nam
- streaming md5sum of contents of a large remote tar
- How to get the background from multiple images by
- Django __str__ returned non-string (type NoneType)
- Evil ctypes hack in python
I think you might be able to use
django-rules
library here. LinkIt is a rule based engine very similar to decision trees and it can be easily integrated with permissions_class framework of DRF.
The best part is you can perform set operations on simple permissions and create complex permissions from them.
Example
Predicates can do pretty much anything with the given arguments, but must always return True if the condition they check is true, False otherwise. Now combining these two predicates..
You can use this new predicate rule
is_object_editable
inside your has_permissions method of permission class.You need to build your own custom http://www.django-rest-framework.org/api-guide/permissions/#custom-permissions as described in the docs.
Something like:
Then in your view:
Now DRF allows permissions to be composed using bitwise operators: & -and- and | -or-.
From the docs:
One way would be to add another permission class which combines existing classes the way you want it, e.g.:
Aside from the custom permission which is simpler approach mentioned in the earlier answer, you can also look for an existing 3rd party that handle a much complex permission handling if necessary.
As of Feb 2016, those handling complex condition permission includes:
Here is a generic solution: