I have a model that accepts an image which is not required.
I'm trying to provide a link to a default image so that when a user later requests the model, I can send them the default image.
I'm using DRF so I don't necessarily have access to reverse
inside a view; based on this response I'm trying to achieve the functionality in the model itself.
# models.py
class Widget(models.Model):
...
def image_url(self):
'''
Returns the url of the image for the model instance.
If no image is found, return the path to the default meal image.
'''
if self.image and hasattr(self.image, 'url'):
return self.image.url
else:
return settings.STATIC_URL + 'img/default/meal.png'
And in my serializer I just add the field instead of the image:
#serializers.py
class WidgetSerializer(serializers.HyperlinkedModelSerializer):
...
class Meta:
model = Widget
fields = ('image_url',
...
)
However, this of course only gives me the relative path of the image, /static/img/default/meal.png
instead of something like http://localhost:8010/static/img/default/meal.png
.
How can I get the base name of the url inside the model so I can respond with the full url? Is this even the right approach?
Also, as a side note, I just visited http://localhost:8010/static/img/default/meal.png
in my browser, and it says the image could not be found. Any ideas about this as well?
--EDIT--
I sort of figured out how to get this working in the view. As of right now though, it only works for a detail view and I'd have to copy the same code into the list view for it to work, which I'm reluctant to do for DRY reasons.
The ideal would be to get the full url of the default image in the serializer, but I'm still not sure how to access the request object there.
# views.py
class WidgetDetail(APIView):
def get_object(self, pk):
try:
return Widget.objects.get(pk=pk)
except Widget.DoesNotExist:
raise Http404
def get(self, request, pk, format=None):
widget = self.get_object(pk)
serializer = WidgetSerializer(
widget,
context={'request': request},
)
serialized_data = serializer.data
if not widget.image:
serialized_data['image'] = request.build_absolute_uri(
settings.STATIC_URL + 'img/default/widget.png')
# print(serialized_data['image'])
return Response(serialized_data)
...
class WidgetList(APIView):
def get(self, request, format=None):
widgets = Widget.objects.all()
serializer = WidgetSerializer(
widgets,
many=True,
context={'request': request},
)
#... Would need to replace null urls here....
return Response(serializer.data)
However, since I'm passing context to the serializer, I should be able to access it there, no?