Во-первых, предостерегающее предупреждение: философия проектирования администратора Django заключается в том, что любой пользователь с доступом к администратору (is_staff==True
) является доверенным пользователем, например, сотрудником, отсюда и обозначение «персонал» длядаже получить доступ к админу.Несмотря на то, что вы можете настроить администратора для ограничения областей, разрешить доступ к вашему администратору любому лицу, не входящему в вашу организацию, считается рискованным, и Django не дает никаких гарантий о какой-либо безопасности на этом этапе.
Теперь, если вы все еще хотитечтобы продолжить, вы можете ограничить практически все, кроме магазинов, просто не назначая эти привилегии пользователю.Вы должны будете предоставить всем владельцам магазинов права на редактирование любой из моделей магазинов, к которым они будут иметь доступ, но все остальное должно быть исключено из их списка разрешений.
Затем для каждой модели, которая должнабыть ограниченным только глазами владельца, вам нужно добавить поле для хранения «владельца», или пользователю разрешен доступ к нему.Вы можете сделать это с помощью метода save_model
в ModelAdmin
, который имеет доступ к объекту запроса:
class MyModelAdmin(admin.ModelAdmin):
def save_model(self, request, obj, form, change):
obj.user = request.user
super(MyModelAdmin, self).save_model(request, obj, form, change)
Тогда вам также необходимо ограничить набор запросов ModelAdmin только теми элементами, которые принадлежаттекущий пользователь:
class MyModelAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(MyModelAdmin, self).get_queryset(request)
if request.user.is_superuser:
return qs
return qs.filter(owner=request.user)
Тем не менее, это ограничит только то, что будет указано в списке, пользователь может по-прежнему играть с URL-адресом для доступа к другим объектам, к которым у него нет доступа, поэтому вам придется переопределить каждый из них.уязвимых представлений ModelAdmin для перенаправления, если пользователь не является владельцем:
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
class MyModelAdmin(admin.ModelAdmin):
def change_view(self, request, object_id, form_url='', extra_context=None):
if not self.queryset(request).filter(id=object_id).exists():
return HttpResponseRedirect(reverse('admin:myapp_mymodel_changelist'))
return super(MyModelAdmin, self).change_view(request, object_id, form_url, extra_context)
def delete_view(self, request, object_id, extra_context=None):
if not self.queryset(request).filter(id=object_id).exists():
return HttpResponseRedirect(reverse('admin:myapp_mymodel_changelist'))
return super(MyModelAdmin, self).delete_view(request, object_id, extra_context)
def history_view(self, request, object_id, extra_context=None):
if not self.queryset(request).filter(id=object_id).exists():
return HttpResponseRedirect(reverse('admin:myapp_mymodel_changelist'))
return super(MyModelAdmin, self).history_view(request, object_id, extra_context)
ОБНОВЛЕНИЕ 06/05/12
Спасибо @ christophe31 за указание, что снабор запросов ModelAdmin
уже ограничен пользователем, вы можете просто использовать self.queryset()
в представлениях изменения, удаления и истории.Это хорошо абстрагирует имя класса модели, делая код менее хрупким.Я также изменил использование filter
и exists
вместо try...except
блока с get
.Таким образом, он более упорядочен и на самом деле приводит к более простому запросу.