Search code examples
pythondjangopermissionsacl

Django: Complex Permission Model


Suppose I have users, projects, memberships and in every membership a role is specified (for example: admin, read-only, user, etc.). The memberships define the relation between users and projects and the corresponding role.

Now I have a problem: how can I use the permission system of Django to assure that only admins can edit projects and the other roles are not allowed to edit projects?

The project list template should look like this:

{% for project in object_list %}
    {# user.has_perm('edit_project', project) #}
{% endfor %}

What is the best way of doing this? How can I implement the permission based on the membership role?


Solution

  • You need to build your own permission system.

    Django's built-in permission system is not suited for what you want to do.

    Build models for the Project. Create a ManyToMany relationship between a User and a Project through a Membership model. This Membership model will have a role field.

    https://docs.djangoproject.com/en/1.10/topics/db/models/#extra-fields-on-many-to-many-relationships has an example that is almost ideally suited for your needs.

    You can not do user.has_perm('edit_project', project) in a template. Django templates do not allow function calls directly with multiple params. I think in your case a custom template tag that takes a User instance, a Project instance, and a string describing the desired permission would be the way to go.