简体   繁体   English

检查Django REST Framework中相关对象的权限

[英]Check permissions on a related object in Django REST Framework

I have defined the following models 我已经定义了以下模型

class Flight(models.Model):
    ...

class FlightUpdate(models.Model):
    flight = models.ForeignKey('Flight', related_name='updates')
    ...

and the following viewset using the NestedViewsetMixin in the REST Framework Extensions 以及使用REST Framework Extensions中的NestedViewsetMixin的以下视图NestedViewsetMixin

class FlightUpdateViewSet(mixins.ListModelMixin,
                      mixins.CreateModelMixin,
                      NestedViewSetMixin,
                      viewsets.GenericViewSet):
    """
    API Endpoint for Flight Updates
    """
    queryset = FlightUpdate.objects.all()
    serializer_class = FlightUpdateSerializer

    def create(self, request, *args, **kwargs):
        flight = Flight.objects.get(pk=self.get_parents_query_dict()['flight'])
        ...

So, to access the FlightUpdates associated with a Flight , the URL is /flights/1/updates/ . 所以,要访问FlightUpdates与相关Flight ,网址是/flights/1/updates/

I want to ensure that people can only create FlightUpdates if they have the permissions to change the Flight object with which the FlightUpdate is associated. 我想确保人们只有在有权更改FlightUpdate相关联的Flight对象时才能创建 FlightUpdates

How would I go about performing the extra check when adding a FlightUpdate ? 添加FlightUpdate时如何进行额外检查? I've tried adding something like this in the viewset, but I'm not sure if it's the best way. 我试过在视图中添加这样的东西,但我不确定它是不是最好的方法。

if not request.user.has_perm('flights.change_flight', flight):
    raise PermissionError()

Note: I'm using django-rules for the object-level permissions implementation. 注意:我正在使用django-rules来实现对象级权限。

I solved this problem by implementing a custom permissions class. 我通过实现自定义权限类解决了这个问题。

from django.core.exceptions import ObjectDoesNotExist

from rest_framework.permissions import BasePermission, SAFE_METHODS

from .models import Flight


class FlightPermission(BasePermission):

    def has_permission(self, request, view):
        if request.method in SAFE_METHODS:
            return True

        try:
            flight = Flight.objects.get(pk=view.kwargs['parent_lookup_flight'])
        except ObjectDoesNotExist:
            return False

        return request.user.has_perm('flights.change_flight', flight)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM