You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何阻止DRF中普通用户(非Staff/Superuser)创建客户?

问题分析

当前使用的permissions.IsAuthenticatedOrReadOnly权限类逻辑为:未认证用户仅能执行只读操作(如GET),已认证用户可执行所有写操作(如POST)。因此普通登录用户(已认证但非staff/superuser)能创建客户是该权限类的预期行为,与你的需求不符。

解决方案

你需要自定义权限类,限制只有is_staff=True或is_superuser=True的用户才能执行POST创建操作,其他用户(包括已认证普通用户和未认证用户)仅能执行只读操作。

步骤1:自定义权限类

在你的app中新建permissions.py文件,添加以下代码:

from rest_framework import permissions

class IsStaffOrSuperuser(permissions.BasePermission):
    def has_permission(self, request, view):
        # 允许所有只读请求(GET/HEAD/OPTIONS)
        if request.method in permissions.SAFE_METHODS:
            return True
        # 写操作仅对staff或超级用户开放
        return request.user and (request.user.is_staff or request.user.is_superuser)

步骤2:替换视图的权限类

修改CustomerPageView的权限配置,替换为自定义权限类:

from .permissions import IsStaffOrSuperuser  # 导入自定义权限类

class CustomerPageView(APIView):
    permission_classes = (IsStaffOrSuperuser,)
    
    def get(self, request):
        customer = Customer.objects.all()
        if not customer.exists():
            return JsonResponse([], safe=False)
        customer_serializer = CustomerSerializer(customer, many=True)
        return JsonResponse(customer_serializer.data, safe=False)
    
    def post(self, request):
        data = json.loads(request.body.decode('utf-8'))
        company_name, contact_person, contact_number, company_address = data.values()
        company_name = company_name.strip()

        chk_company_name = Customer.objects.filter(company_name__iexact=company_name)
        if chk_company_name:
            return JsonResponse({'label':'company_name', 'message':'Customer Already Exists'}, status=500)
        
        if len(company_name) == 0:
            return JsonResponse({'label':'company_name', 'message':'Invalid Entry'}, status=500)
        
        createCustomerInstance = Customer.objects.create(
            company_name=company_name,
            contact_person=contact_person,
            contact_number=contact_number,
            company_address=company_address,
        )

        return JsonResponse({'message': f"Successfully added {company_name}", 'variant': 'success'})

可选优化建议

你的POST方法直接解析request.body,更符合DRF规范的做法是使用序列化器处理请求数据,自动完成数据验证和字段解析,示例如下:

def post(self, request):
    serializer = CustomerSerializer(data=request.data)
    if serializer.is_valid():
        company_name = serializer.validated_data['company_name'].strip()
        if Customer.objects.filter(company_name__iexact=company_name).exists():
            return JsonResponse({'label':'company_name', 'message':'Customer Already Exists'}, status=500)
        serializer.save()
        return JsonResponse({'message': f"Successfully added {company_name}", 'variant': 'success'})
    return JsonResponse(serializer.errors, status=400)

内容的提问来源于stack exchange,提问作者lolideppt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 11:01:28