views:

104

answers:

1

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?
+1  A: 

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 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!

lazerscience
Your first peace of code worked great. I also found it here:http://www.ibm.com/developerworks/opensource/library/os-django-admin/index.html
Jonathan