Create a per-object permission¶
django-authority provides a super simple but nifty feature called per-object permission. A description would be:
Attach a <codename> to an object
Attach a <codename> to an user
If the user has <codename> and the object has <codename> then do-something,
otherwise do-something-else.
This might sound strange but let’s have a closer look on this pattern. In terms of users and flatpages a visual example would be:
The user is allowed to review the flatpage “Events”.
You are not limited to a 1:1 relation, you can add this codename
to
multiple objects:
The user is allowed to review the flatpages “Events” and “Contact”.
And you can do this with any objects in any direction:
The user is allowed to review the flatpages “Events” and “Contact”. Another user is allowed to publish the flatpage “Events”.
Create per-object permissions¶
Creating per-object permissions is super simple. See this piece of permission class code:
class FlatPagePermission(BasePermission):
label = 'flatpage_permission'
checks = ('review',)
authority.register(FlatPage, FlatPagePermission)
This permission class is similar to the one we already created in Create a basic permission but we added the line:
checks = ('review',)
This tells the permission class that it has a permission check (or codename
)
review
. Under the hood this check gets translated to review_flatpage
(review_<modelname>
).
Important
Be sure that you have understand that we have not written any
line of code yet. We just added the codename
to the checks attribute.
Attach per-object permissions to objects¶
Please see Handling permissions using Django’s admin interface for this.
Check per-object permissions¶
As we noted above, we have not written any permission comparing code yet. This is your work. In theory the permission lookup for per-object permissions is:
if <theuser> has <codename> and <object> has <codename>:
return True
else:
return False
Important
The syntax is similiar to the permission checks we’ve already seen in Create a basic permission for the basic permissions but now we have to pass each function a model instance we want to check!
In your python code¶
from myapp.permissions import FlatPagePermission
def my_view(request):
check = FlatPagePermission(request.user)
flatpage_object = Flatpage.objects.get(url='/homepage/')
if check.review_flatpage(flatpage_object):
print "Yay, you can change *this* flatpage!"
Using the view decorator¶
from django.contrib.auth import Flatpage
from authority.decorators import permission_required_or_403
@permission_required_or_403('flatpage_permission.review_flatpage',
(Flatpage, 'url__iexact', 'url')) # The flatpage_object
def my_view(request, url):
# ...
See Check permissions using the decorator how the decorator works in detail.
In your templates¶
{% ifhasperm "flatpage_permission.review_flatpage" request.user flatpage_object %}
Yay, you can change *this* flatpage!
{% else %}
Nope, sorry. You aren't allowed to change *this* flatpage.
{% endifhasperm %}
See Check permissions in templates how the template tag works in detail.