inserting the request’s user during put-as-create operations

I am using the following mixin.

class PutAsCreateMixin(object):
    """
    The following mixin class may be used in order to support
    PUT-as-create behavior for incoming requests.
    """
    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object_or_none()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)

        if instance is None:
            if not hasattr(self, 'lookup_fields'):
                lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
                lookup_value = self.kwargs[lookup_url_kwarg]
                extra_kwargs = {self.lookup_field: lookup_value}
            else:
                # add kwargs for additional fields
                extra_kwargs = {field: self.kwargs[field] for field in self.lookup_fields if self.kwargs[field]}
            serializer.save(**extra_kwargs)
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        serializer.save()
        return Response(serializer.data)

and I have the following view.

class OwnStarPutDestroyView(CoreView, PutAsCreateMixin, MultipleFieldMixin, PutDeleteAPIView):
    serializer_class = StarSerializer
    queryset = Star.objects.all()
    permission_classes = [IsAuthenticated, AddStars]
    lookup_fields = ['upload_id', 'user_id']

    @property
    def overwrite_channel(self) -> Channel:
        # return the associated channel object for the view
        # by referencing the upload from upload-id in the url
        upload = get_object_or_404(Upload, id=self.kwargs.get('upload_id'))
        return upload.channel

    @property
    def member(self) -> Member:
        # return the associated member object for the
        # authenticated user by referencing upload object's
        # box attribute to lookup the object
        upload = get_object_or_404(Upload, id=self.kwargs.get('upload_id'))
        return get_object_or_404(Member, user=self.request.user, box=upload.box)

    def get_object(self):
        # explicitly set the user-id kwarg by referencing
        # the request's user because we cannot set the same
        # anywhere else during put-as-create operations
        self.kwargs['user_id'] = self.request.user.id
        return super(OwnStarPutDestroyView, self).get_object()
    path('uploads/<int:upload_id>/stars/me/', views.OwnStarPutDestroyView.as_view(), name='own-stars-put-destroy'),

As you can see here, I am setting the user_id to the kwargs before getting the object. This enables the mixin to include the kwarg as a parameter while checking if the object exists

However, I don't think that this seems right. Is there a better way to do the same?



Read more here: https://stackoverflow.com/questions/66273326/inserting-the-requests-user-during-put-as-create-operations

Content Attribution

This content was originally published by CosmicReindeer at Recent Questions - Stack Overflow, and is syndicated here via their RSS feed. You can read the original post over there.

%d bloggers like this: