Мой подход заключается в добавлении метода к модели:
class YourModelWithOwnership(models.model):
...
def user_can_manage_me(self, user):
return user == self.user or user.has_perm('your_app.manage_object')
Затем я вызываю этот метод всякий раз, когда требуется проверка разрешения, и предпринимаю некоторые действия в зависимости от результата. Так что для представления это будет
from django.shortcuts import get_object_or_404
...
def view_func(request, item_id):
item = get_object_or_404(YourModelWithOwnership, id=item_id) # or whatever is needed to get the object
if not item.user_can_manage_me(request.user):
# user not allowed to manage
...
else:
...
Позже я, вероятно, пойму, что это все еще довольно типичный код для записи в каждом представлении, которое нуждается в этом тесте, поэтому я реализовал исключение, которое выдается, когда пользователь не может управлять объектом ...
class CannotManage(Exception):
pass
... и добавьте еще один метод к модели:
from django.db import models
from django.shortcuts import get_object_or_404
class YourModelWithOwnership(models.model):
...
@classmethod
def get_manageable_object_or_404(cls, user, *args, **kwds):
item = get_object_or_404(cls, *args, **kwds)
if not item.user_can_manage_me(user):
raise CannotManage
return item
Тогда в функциях просмотра это можно использовать:
def view_func(request, item_id):
item = YourModelWithOwnership.get_manageable_object_or_404(request.user, id=item_id)
...
Это, конечно, вызовет исключение, когда пользователь не является владельцем и не имеет соответствующего разрешения. Это исключение может быть обработано в методе process_exception()
пользовательского класса промежуточного программного обеспечения *1018*, так что существует единый обработчик для всех случаев, когда пользователю не разрешено связываться с объектом.