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

Django项目中SavedClass视图POST请求权限控制及模型字段权限配置求助

Hey there! Let's break down how to fix your two issues step by step—since you're new to Django REST Framework, I'll keep explanations straightforward so you can follow along easily.

Issue 1: Restrict POST requests to create SavedClass records only for the current user

Right now, your SavedClassView's POST method just returns a 403, which isn't what you want. Instead, we need to ensure that when a user creates a SavedClass, the user field is automatically set to the currently logged-in user (and prevent the frontend from passing a different user ID).

Step 1: Update the Serializer

First, mark the user field as read-only in your SavedClass_serializer so the frontend can't override it:

# serializers.py
class SavedClass_serializer(serializers.ModelSerializer):
    class Meta:
        model = models.SavedClass
        fields = '__all__'
        read_only_fields = ['user']  # Make user field read-only to block frontend input

Step 2: Fix the SavedClassView

Update your SavedClassView to:

  1. Properly handle POST requests (remove the hardcoded 403)
  2. Automatically assign the current user to the SavedClass record on creation
  3. Fix the get_queryset to use the User object directly (cleaner than using id)
# views.py
class SavedClassView(LoginRequiredMixin, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
    serializer_class = serializers.SavedClass_serializer
    lookup_field = 'id'  # Needed for delete operations to find the correct record

    def get_queryset(self):
        # Filter SavedClasses to only the current logged-in user (use User object directly)
        return models.SavedClass.objects.filter(user=self.request.user)

    def get(self, request):
        return self.list(request)

    def post(self, request, *args, **kwargs):
        # Let the CreateModelMixin handle creation, we'll set the user in perform_create
        return self.create(request, *args, **kwargs)

    def delete(self, request, id=None, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

    def perform_create(self, serializer):
        # Automatically set the user to the currently logged-in user
        serializer.save(user=self.request.user)

Now, when a user sends a POST request to create a SavedClass, the user field will always be set to their own account—no way to spoof another user's ID.

Issue 2: Restrict is_registered field modifications to admins only

We need to ensure that only superusers can change the is_registered value. There are two clean ways to handle this; let's cover both so you can choose what fits your workflow.

Option 1: Control via the Serializer

Modify the update method in your SavedClass_serializer to strip out the is_registered field if the user isn't an admin:

# serializers.py
class SavedClass_serializer(serializers.ModelSerializer):
    class Meta:
        model = models.SavedClass
        fields = '__all__'
        read_only_fields = ['user']

    def update(self, instance, validated_data):
        # Get the current user from the request context
        current_user = self.context['request'].user
        
        # If the user isn't a superuser, remove is_registered from the data to update
        if not current_user.is_superuser:
            validated_data.pop('is_registered', None)
        
        # Proceed with the normal update
        return super().update(instance, validated_data)

Option 2: Control via the View

First, add mixins.UpdateModelMixin to your SavedClassView inheritance (to handle PUT requests), then check for admin permissions before allowing is_registered changes:

# views.py
class SavedClassView(LoginRequiredMixin, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.UpdateModelMixin, mixins.DestroyModelMixin, generics.GenericAPIView):
    serializer_class = serializers.SavedClass_serializer
    lookup_field = 'id'

    def get_queryset(self):
        return models.SavedClass.objects.filter(user=self.request.user)

    def get(self, request):
        return self.list(request)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

    def put(self, request, id=None, *args, **kwargs):
        # Check if user is trying to modify is_registered without admin rights
        if 'is_registered' in request.data and not request.user.is_superuser:
            return Response(
                {"detail": "Only administrators can modify the is_registered field."},
                status=status.HTTP_403_FORBIDDEN
            )
        return self.update(request, *args, **kwargs)

    def delete(self, request, id=None, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

This option gives you more explicit control and returns a clear error message when a non-admin tries to modify the field.

Final Notes

  • Don't forget to add the UpdateModelMixin to your view if you choose Option 2 (or if you want to allow users to update other fields like is_attended).
  • Test both scenarios: log in as a regular user and try to create a SavedClass with another user's ID (it should ignore the user input and use your own), then try to modify is_registered (it should block you). Log in as an admin to confirm you can modify the field.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 19:47:39