• python3
  • django >= 1.10


  1. Download a bdist_wheel artifact from the latest successful ci pipeline:



    Replace X.X with the version you downloaded:

    pip install django-model-permissions-X.X-py3-none-any.whl
  2. Add the app to INSTALLED_APPS:

        # ...


    This replaces the default backend with an extended version. (See Permission Function)

    If you don’t want to retain django’s user and group permissions, use the ObjectBackend instead:

  4. Optional: Redirect all PermissionDenied errors to LOGIN_URL:

        # ...


  1. Create a Permission Function called get_permissions as a method on your model:

    It should return a list of permissions the given user has for this object.

    class MyModel(models.Model):
        owner = models.ForeignKey(settings.AUTH_USER_MODEL, models.CASCADE)
        def get_permissions(self, user):
            if user.is_anonymous:
            permissions = ['myapp.add_mymodel']
            if not user.is_staff and not user == self.owner:
                return permissions
            return permissions + [
  2. Use the model_permissions views or mixins:

    Since it seems to be very hard to inject the object permissions in a context_processor, django-model-permissions comes with ready-to-use views and mixins:

    from model_permissions.views import CreateView, UpdateView, DeleteView
    class MyModelCreateView(CreateView):
        model = MyModel
    class MyModelCreateView(UpdateView):
        model = MyModel
        fields = ('name', 'description', 'owner')
        required_permission = 'myapp.change_mymodel'
    class MyModelCreateView(DeleteView):
        model = MyModel
        required_permission = 'myapp.delete_mymodel'

    The main functionality is split into 2 mixins.


    Use the model_permissions.views.PermissionMixin if you want both.

    The model_permissions.views.PermissionContextMixin adds a 'object_perms' variable to the template context. Use it if your view is public and you just want to access the permissions in the template.

    from model_permissions.views import PermissionContextMixin
    from django.views.generic import DetailView
    from myapp.models import MyModel
    class MyModelDetailView(PermissionContextMixin, DetailView):
        model = MyModel
        fields = ('name', 'description', 'owner')

    Use the model_permissions.views.RequirePermissionMixin to restrict access to a view based on object permissions:

    from model_permissions.views import UpdateView
    from myapp.models import MyModel
    class MyModelDetailView(UpdateView):
        model = MyModel
        required_permission = 'myapp.change_mymodel'
        fields = ('name', 'description', 'owner')
  3. Use permissions in your templates:

    If you’re using the model_permissions.views.PermissionContextMixin or one of its subclasses your context will contain object_perms and <model_label>_perms variables:


    The second example also shows the usage of Related Permissions.

    {# forum_detail.html #}
    {% if forum_perms.myforum.change_forum %}
        <a href="{% url "myforum:change_forum" forum.pk %}">Edit</a>
    {% endif %}
    {# or #}
    {% if object_perms.myforum.add_thread %}
        <a href="{% url "myforum:add_thread" forum.pk %}">Add Thread</a>
    {% endif %}

    To get permissions for another object or in views that are not subclassing model_permissions.views.PermissionContextMixin you can use the get_perms template tag:

    Without argument it will use the object variable in the context. The resulting perms lookup dict will not contain any object permissions if there is no object.

    {# thread_detail.html #}
    {% load model_permissions %}
    {% get_perms as thread_perms %}
    {% if thread_perms.myforum.change_thread %}
        <a href="{% url "myforum:change_thread" thread.pk %}">{{ thread }}</a>
    {% else %}
        {{ thread }}
    {% endif %}
    {% for post in posts %}
        {% get_perms post as post_perms %}
            {% if post_perms.myforum.change_post %}
                <a href="{% url "myforum:change_post" post.pk %}">{{ post }}</a>
            {% else %}
                {{ post }}
            {% endif %}
            <p>{{ post.text }}</p>
    {% endfor %}

For more information see the Manual and Modules.