Home > Back-end >  How to force a value when creating with django-rest-framework ModelViewSet?
How to force a value when creating with django-rest-framework ModelViewSet?

Time:11-09

I have an api where users can create different objects. If the user is part of the staff, he can create the object with all the values he wants. However, if the user is not part of the staff, I want to force the value of a particular field.

I added the following code to a viewset that works well:

    @swagger_auto_schema(responses={201: CategoryProductSerializer})
    def create(self, request, *args, **kwargs):
        if not self.request.user.is_staff:
            request.data['client']=request.user.profil.client.pk
        print(request.data)
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers)

    def perform_create(self, serializer):
        serializer.save() 

How can I "generalize" this to all my modelviewsets? The important part of this create that must be common to all my viewsets is :

if not self.request.user.is_staff:
   request.data['client']=request.user.profil.client.pk

CodePudding user response:

Add the user to the context like this

serializer = self.get_serializer(data=request.data, context={"user": request.user})

then use the serializers validate or validate_client method to perform your checking

if not self.context['user'].is_staff:
    pass

CodePudding user response:

Since the question is basically "How to generalize". I think you should create your own middleware.

class SimpleMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.

    def __call__(self, request):
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.
        return response

    def process_view(self,request,view_func,*view_args,**view_kwargs):
           if not request.user.is_staff:
               request.client=request.user.profil.client.pk

Make sure you include your middleware in your MIDDLEWARE block of settings.py. ALso make sure you add it AFTER the AuthenticationMiddleware.

  • Related