如何阻止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
相关产品推荐
相关产品推荐

