I am making a test that partial updates or patch some fields in my Product model. I should be enable to update any fields in my Product model. In my serializer, I have a url builder from the request object. However, request
is not passed on my serializer or it is a None type. Thus, I am getting an error: AttributeError: 'NoneType' object has no attribute 'build_absolute_uri'
How do I pass a request to my serializer?
def test_patch_products(self):
data = {
'description': 'This is an updated description.',
'type': 'New'
}
...
...
response = self.client.patch('/data/products/1/',
data=data, format='json')
In my view:
def partial_update(self, request, pk=None):
product= get_object_or_404(Product, pk=pk)
serializer = ProductSerializer(product,
data=self.request.data, partial=True,
)
if serializer.is_valid():
serializer.save(uploaded_by=self.request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
In my serializer:
class ProductSerializer(serializers.ModelSerializer):
uploaded_by= serializers.StringRelatedField()
thumbnail = serializers.SerializerMethodField()
class Meta:
model = CaptureGroup
fields = ('__all__')
def get_thumbnail(self, object):
request = self.context.get('request') # request is None here
thumbnail = object.thumbnail.url
return request.build_absolute_uri(thumbnail) # here is the url builder
In your view, you can pass some additional context to your serializer. That's useful to manipulate your request.
# views.py
def partial_update(self, request, pk=None):
product= get_object_or_404(Product, pk=pk)
serializer = ProductSerializer(product,
data=request.data, partial=True,
context={'request': request}, # you're missing this line
)
# ...
And then you can manipulate it your serializer with self.context.get('request')
but I see you already got that part in your code.
In case you would like more information, here is the link to DRF documentation about this.