python - Django Rest Framework 自定义权限验证
问题描述
我有一个自定义 ViewSet,可以对数据库进行复合查询和更新。我想建立不同级别的权限,这样我可以授权一些用户在视图上发送GET方法,并允许其他一些用户请求POST和PUT方法。
在我找到的文档中,所有权限都被认为是类视图的全局权限,所以我不知道如何对方法应用一些权限,以及对 ViewSet的和方法应用list
一些不同的权限。create
update
这是 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()
。
解决方案
视图集的list()
,create()
和方法由路由器映射到相应的 HTTP 方法。update()
因此,您可以创建一个自定义权限来检查 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
并在视图集上指定:
class ReservationCompositionViewSet(viewsets.ViewSet):
permission_classes = (ReservationCompositionPermission, )
推荐阅读
- javascript - 如何通过单击具有幻灯片效果的锚点而不是直接加载页面来打开网站中的另一个页面?
- c++ - 如何从外部进程访问视频帧?
- r - 根据公共 ID 将行连接成一行
- java - Vaadin 行的网格编号
- batch-file - 在批处理文件中使用 7zip“排除通配符”
- r - 使用 downloadHandler 时如何修复“找不到文件”?
- keras - 使用 Keras LSTM 预测未来值
- javascript - JS Array.prototype.sort() 在 Firefox 中失败,在 Chrome 中有效
- python - 为分类问题添加注意力机制
- arrays - 从数组中的工作表返回值