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.