Skip to main content
 首页 » 编程设计

python之Django Rest Framework 自定义权限验证

2024年09月07日33davidwang456

我有一个自定义 ViewSet,它对数据库进行组合查询和更新。我想建立不同级别的权限,所以我可以授权一些用户在 View 上发送GET方法,而允许其他一些用户请求POST和PUT 方法。

In the documentation I have found ,所有权限都被认为是类 View 的全局权限,所以我不知道如何将某些权限应用于 list方法,以及对 create 的一些不同权限和 update ViewSet 的方法。

这是ViewSet的主要代码:

class ReservationCompositionViewSet(viewsets.ViewSet): 
 
    def list(self, request, pk): 
            reservation = models.Reservation.objects.filter(booking=pk).order_by('timestamp').last() 
            if reservation == None: 
                raise CustomValidation(_('There is not such Reservation: {}'.format(pk)), 'booking', status.HTTP_400_BAD_REQUEST) 
 
            result_set = serializers.ReservationSerializer(reservation).data 
 
            result_set['pax'] = self.get_reservation_people(reservation) 
            result_set['itinerary'] = self.get_reservation_composition(reservation) 
 
            return Response(result_set) 
    ... 
 
    def create(self, request): 
        reservation_data = request.data 
        user = request.user 
 
        reservation = models.Reservation() 
        reservation.booking = reservation_data['booking'] 
        reservation.agency = models.Agency.objects.get(id=reservation_data['agency']) 
        reservation.comment = reservation_data.pop('comment', None) 
        reservation.status = reservation_data.pop('status', 'UNCONFIRMED') 
        if reservation.status == None: 
            reservation.status = 'UNCONFIRMED' 
        reservation.arrival_date = reservation_data['arrival_date'] 
        reservation.departure_date = reservation_data['departure_date'] 
        reservation.confirmation = reservation_data.pop('confirmation', None) 
        reservation.is_invoiced = reservation_data['is_invoiced'] 
        reservation.user = user 
 
        reservation.save() 
 
        reservation_to_return = serializers.ReservationSerializer(reservation).data 
        reservation_to_return['pax'] = self.save_reservation_people(reservation, reservation_data.pop('pax')) 
        reservation_to_return['itinerary'] = self.save_reservation_components(reservation, reservation_data.pop('itinerary')) 
 
        return Response(reservation_to_return) 
 
    def update(self, request, pk): 
        reservation_data = request.data 
        user = request.user 
 
        reservation = self.save_reservation(reservation_data, user, pk) 
 
        reservation_to_return = serializers.ReservationSerializer(reservation).data 
        reservation_to_return['pax'] = self.save_reservation_people(reservation, reservation_data.pop('pax')) 
        reservation_to_return['itinerary'] = self.save_reservation_components(reservation, reservation_data.pop('itinerary')) 
 
        return Response(reservation_to_return) 
        ... 

我想验证用户有 can_view方法时的权限 list()被称为,can_edit create()时的许可或 update()方法被调用。

请您参考如下方法:

View 集的list()、create() 和update() 方法是mapped通过路由器到相应的 HTTP 方法。

因此,您可以创建自定义权限来检查 HTTP 方法的类型以确定正在发生的操作。

例如:

from rest_framework import permissions 
 
class ReservationCompositionPermission(permissions.BasePermission): 
 
    def has_permission(self, request, view): 
        if request.method == 'GET': 
            return request.user.has_perm('can_view') 
        elif request.method in ('POST', 'PUT', 'PATCH'): 
            return request.user.has_perm('can_edit') 
        return False 

并在 View 集上指定:

class ReservationCompositionViewSet(viewsets.ViewSet): 
    permission_classes = (ReservationCompositionPermission, )