Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to prevent Django Admin Users from changing other Admin Users' profile data?

I have Admin User extended/subclassed by Teacher class.

How to prevent Teachers from seeing and changing other Teachers' profile data and Teachers are able to change their own records/rows only? Thanks in advance!

like image 668
Viet Avatar asked Dec 18 '22 02:12

Viet


2 Answers

I'm not sure I understand exactly what you're trying to do, but if what's in your mind is having the built-in user administration pages working slightly differently for Teacher users, then I believe you just have to extend UserAdmin, and override the queryset method.

class TeacherSpecificUserAdmin(UserAdmin):
  def queryset(self, request):
    if request.user.is_teacher():
      return Teacher.objects.filter(pk=request.user.pk)
    return UserAdmin.queryset(self, request)

That will take care of disallowing Teachers to edit or delete other records, because if you look in the ModelAdmin code, change_view and delete_view method use the queryset returned from queryset method to get the object to change or delete.

One more tweak is necessary, because the view used to change the password in UserAdmin doesn't use the same system as the others views to get the object to change. Just override it in your new class :

...
def user_change_password(self, request, id):
  if request.user.is_teacher() and request.user.pk != int(id):
    # PermissionDenied is in django.core.exceptions
    raise PermissionDenied
  return UserAdmin.user_change_password(self, request, id)
...

After that, you just have to prevent Teachers to add new users, or delete their own record. Do that either using the default django's permission framework, or by overriding has_add_permission and has_delete_permission methods.

Have a look in the ModelAdmin source code if you want more info (in contrib/admin/options.py).

like image 121
Clément Avatar answered Dec 19 '22 15:12

Clément


There probably isn't a build in way to do this.

See the permission docs:

Permissions are set globally per type of object, not per specific object instance. For example, it's possible to say "Mary may change news stories," but it's not currently possible to say "Mary may change news stories, but only the ones she created herself" or "Mary may only change news stories that have a certain status, publication date or ID." The latter functionality is something Django developers are currently discussing.

However, object level permissions are coming, apparently.

like image 40
Nick Presta Avatar answered Dec 19 '22 16:12

Nick Presta