Ограничить доступ только к собственному контенту django
Я пишу API, используя django-tastypie. У меня есть две нестандартные проблемы с разрешениями, которые, я надеюсь, может исправить django-guardian.
У меня есть две группы пользователей: клиницисты и пациенты. Клиницисты должны иметь доступ к объектам, принадлежащим только их пациентам, а пациенты должны иметь доступ только к объектам, созданным ими самими.
Мой код выглядит следующим образом:
class UserResource(ModelResource):
class Meta:
queryset = User.objects.all()
resource_name = 'auth/user'
excludes = ['email', 'password', 'is_superuser']
class BlogPostResource(ModelResource):
author = fields.ToOneField(UserResource, 'author', full=True)
class Meta:
queryset = BlogPost.objects.all()
resource_name = 'posts'
allowed_methods = ["get", "post"]
# Add it here.
authentication = BasicAuthentication()
authorization = DjangoAuthorization()
filtering = {
'author': ALL_WITH_RELATIONS,
}
Как я могу использовать разрешения, чтобы ограничить доступ к этому BlogPostResource
?
2 ответа
Я основал свое окончательное решение на ответе JamesO. Проблема с его ответом заключалась в том, что он был написан для более старой версии django-tastypie до Authorization
класс был переписан. Вот мой код для дальнейшего использования:
from tastypie.authorization import Authorization
from django.contrib.auth.models import Group
from extendedusers.models import ExtendedUser
class CustomAuthorization(Authorization):
def read_list(self, object_list, bundle):
clinician_group = Group.objects.get(name='clinician')
if bundle.request and hasattr(bundle.request, 'user'):
if clinician_group in bundle.request.user.groups.all():
patients = ExtendedUser.objects.filter(clinician_id=bundle.request.user.id)
object_list = object_list.filter(author__id__in=patients)
else:
object_list = object_list.filter(author=bundle.request.user)
return object_list
else:
return object_list.none()
Вы можете достичь этого с помощью пользовательского класса Authorization, например что-то вроде:
class CustomAuthorization(Authorization):
def apply_limits(self, request, object_list):
...
clin_group = Group.objects.get(name='YOUR GROUP')
if request and hasattr(request, 'user'):
if clin_group in request.user.groups.all():
object_list = object_list.filter(user__in=request.user.patients.all()) # or however you stop clinician>patient relation
else:
object_list = object_list.filter(user=request.user)
return object_list