Question

I'm using django's admin to let users manage model instances of a specific model. Each user should be able to manage only his model instances. (except for administrators which should manage all).

How do I filter the objects in the admin's changelist view?

Thoughts:

  • I guess the most elegant approach would be to use Object-level permissions. Anyone aware of an implementation of this?
  • Is it possible to do by overriding the admin's view using ModelAdmin.changelist_view?
  • Does list_select_related have anything to do with it?
Was it helpful?

Solution

You can override the admin's queryset-method to just display an user's items:

    def queryset(self, request):
        user = getattr(request, 'user', None)
        qs = super(MyAdmin, self).queryset(request)
        if user.is_superuser:
            return qs
        return qs.filter(user=user)

Besides that you should also take care about the has_change_permission and has_delete_permission-methods, eg like:

    def has_delete_permission(self, request, obj=None):   
        if not request.user == obj.user and not request.user.is_superuser:
            return False
        return super(MyAdmin, self).has_delete_permission(request, obj)

Same for has_change_permission! list_select_related is only used when getting the admin's queryset to get also related data out of relations immediately, not when it is need!

If your main goal is only to restrict a user to be not able to work with other's objects the above approch will work, if it's getting more complicated and you can't tell a permissions simply from ONE attribute, like user, have a look into django's proposal's for row level permissions!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top