首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在drf中的项目中,我的终结点是"api/v1/ invoice /#id/“,因此我只想将查看权限授予此发票的作者

在drf中的项目中,我的终结点是"api/v1/ invoice /#id/“,因此我只想将查看权限授予此发票的作者
EN

Stack Overflow用户
提问于 2021-11-01 06:19:37
回答 2查看 42关注 0票数 0

我有一个端点/api/v1/invoice/#id/

我希望只有此发票的作者应该能够查看发票或工作人员应该能够查看此发票,超级用户应该能够查看,更新,删除发票

我尝试在我的应用程序中创建permissions.py文件:

permissions.py

代码语言:javascript
复制
from rest_framework.permissions import BasePermission


class AuthorGetStaffGetAdminAll(BasePermission):
    edit_methods = ("PUT", "PATCH", "DELETE")

    def has_permission(self, request, view):
        if request.user.is_authenticated:
            return True
        return False

    def has_object_permission(self, request, view, obj):
        if request.user.is_superuser:
            return True

        if obj.author == request.user and request.method not in self.edit_methods:
            return True

        if request.user.is_staff and request.method not in self.edit_methods:
            return True

        return False

serializer.py

代码语言:javascript
复制
class InvoiceSerializer(serializers.ModelSerializer):
    order = serializers.SlugRelatedField(slug_field='id', queryset=order.Order.objects.all())
    id = serializers.CharField(max_length=100, read_only=True)
    class Meta:
        model = invoice.Invoice
        fields = ['id', 'invoice_series', 'order', 'payment_id']

view.py

代码语言:javascript
复制
class InvoiceDisplayView(APIView):
    permission_classes = [AuthorGetStaffGetAdminAll]

    def get(self, request, invoice_id):
        invoice = Invoice.objects.get(id__iexact=invoice_id)
        serializer = InvoiceSerializer(invoice)
        return Response(serializer.data)

urls.py

代码语言:javascript
复制
from django.urls import path
from . import views

urlpatterns = [
    path('v1/invoices/<str:invoice_id>/', views.InvoiceDisplayView.as_view(), name="invoice_view"),
]
EN

回答 2

Stack Overflow用户

发布于 2021-11-01 09:50:56

APIView没有对象级权限检查。您可以使用RetrieveUpdateDestroyAPIView更新您的APIView:

代码语言:javascript
复制
class InvoiceDisplayView(RetrieveUpdateDestroyAPIView):
    
    lookup_field = 'invoice_id'  # primary key
    permissions_classes = [IsAuthenticatedAndOwner]
    queryset = Invoice.objects.all()
    serializer_class = InvoiceSerializer

如果你的主键是invoice_id,你可以这样做,并且不需要get方法,这个方法单独用于put,update,delete和get,通常primary_key只是id或pk,在这种情况下,lookup_field将是'id‘或'pk’,你也需要更新你的urls:

代码语言:javascript
复制
urlpatterns = [
    path('v1/invoices/<int:id>/', views.InvoiceDisplayView.as_view(), name="invoice_view"),
]
票数 1
EN

Stack Overflow用户

发布于 2021-11-01 09:49:47

因为你使用的是APIView而不是泛型视图,所以你必须显式地调用check_object_permissionsthis answer会解释一切。

get方法应该如下所示:

代码语言:javascript
复制
    def get(self, request, invoice_id):
        invoice = Invoice.objects.get(id__iexact=invoice_id)
        self.check_object_permissions(request, invoice)   # This calls permissions
        serializer = InvoiceSerializer(invoice)
        return Response(serializer.data)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69793238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档