61👍
Example (untested):
class MySerializer(serializers.ModelSerializer):
thumbnail_url = serializers.SerializerMethodField('get_thumbnail_url')
def get_thumbnail_url(self, obj):
return self.context['request'].build_absolute_uri(obj.thumbnail_url)
The request must available to the serializer, so it can build the full absolute URL for you. One way is to explicitly pass it in when the serializer is created, similar to this:
serializer = MySerializer(account, context={'request': request})
12👍
Thanks, shavenwarthog. Your example and documentation reference helped enormously. My implementation is slightly different, but very close to what you posted:
from SomeProject import settings
class ProjectSerializer(serializers.HyperlinkedModelSerializer):
thumbnail_url = serializers.SerializerMethodField('get_thumbnail_url')
def get_thumbnail_url(self, obj):
return '%s%s' % (settings.MEDIA_URL, obj.thumbnail)
class Meta:
model = Project
fields = ('id', 'url', 'name', 'thumbnail_url')
- [Django]-WARNING: Running pip as the 'root' user
- [Django]-Rendering a value as text instead of field inside a Django Form
- [Django]-How to add a new field to a model with new Django migrations?
7👍
To get the url of a file which uses FileField you can just call the url attribute of the FieldFile (this is the file instance not the field), it use the Storage class to determine the url for this file. It’s very straightforward if you are using a external storage like Amazon S3 or if your storage changes.
The get_thumbnail_url would be like this.
def get_thumbnail_url(self, obj):
return obj.thumbnail.url
You can also use it in the template this way:
{{ current_project.thumbnail.url }}
- [Django]-Django count RawQuerySet
- [Django]-Using Django Rest Framework, how can I upload a file AND send a JSON payload?
- [Django]-The STATICFILES_DIRS setting should not contain the STATIC_ROOT setting
6👍
I found it annoying to write the same code for a serialized method field.
If you have set correctly the MEDIA_ROOT
to your S3 bucket URL, you can add a field to the serializer like:
class ProjectSerializer(serializers.ModelSerializer):
logo_url = serializers.URLField(read_only=True, source='logo.url')
class Meta:
model = Project
logo is an ImageField in the model. it must not be nullable in order to avoid errors like ValueError: The 'img' attribute has no file associated with it.
I only use .build_absolute_uri
in a serializer methodfield to return absolute urls that use other views in my API. for example, in my project there is an URL /webviews/projects/<pk>
that shows, a title and a button that collects some user input (i.e. not exactly what you would do with suffixes, as it’s not a plain representation of the resource but includes some logic instead). the end point /projects/<pk>/
contains a field “webview_url” ponting there, which is generated with SerializerMethodField. it’s not media.
- [Django]-How to do SELECT MAX in Django?
- [Django]-Can WordPress be replaced by a Framework like Django or Ruby on Rails?
- [Django]-Get request data in Django form
6👍
No need for any overrides or customizations. DRF handles it automatically. Take a look at to_representation
method of FileField
(source):
def to_representation(self, value):
if not value:
return None
use_url = getattr(self, 'use_url', api_settings.UPLOADED_FILES_USE_URL)
if use_url:
if not getattr(value, 'url', None):
# If the file has not been saved it may not have a URL.
return None
url = value.url
request = self.context.get('request', None)
if request is not None:
return request.build_absolute_uri(url)
return url
return value.name
Note that it won’t work if the context of the serializer is not set properly. If you’re using ViewSet
s, no worries, everything is done silently but if you’re instantiating the serializer manually you have to pass in the request in the context.
context = {'request': request}
serializer = ExampleSerializer(instance, context=context)
return Response(serializer.data)
https://www.django-rest-framework.org/community/3.0-announcement/#file-fields-as-urls
- [Django]-Why Should I use Redis when I have PostgreSQL as my database for Django?
- [Django]-Django, ImportError: cannot import name Celery, possible circular import?
- [Django]-Custom QuerySet and Manager without breaking DRY?
1👍
Just pass the context and pass request object. if you are using @api_view
serializer = CustomerSerializer(customer, context={"request": request})
For ViewSet user get_serializer_context method
class ProjectViewSet(viewsets.ModelViewSet):
queryset = Project.objects.all()
serializer_class = ProjectSerializer
def get_serializer_context(self):
return {'request': self.request}
- [Django]-Django admin action without selecting objects
- [Django]-How to cache Django Rest Framework API calls?
- [Django]-Django admin: make field editable in add but not edit
1👍
Just pass this "context={'request': request}"
argument where you call your model serializer class to serialize the object. You can follow the below snippet to get the complete URL field.
serialized_object = serializers.MySerializer(data, many=true, context={'request': request})
- [Django]-Django – Circular model import issue
- [Django]-Django delete superuser
- [Django]-Vscode html autoformat on django template
1👍
if you cannot access extra context in your serializer using Viewsets, try register your router with a basename in urls.py:
router.register('projects', ProjectViewSet, basename='project')
you can use build_absolute_uri:
def get_thumbnail_url(self, obj):
return self.context.get('request').build_absolute_uri(obj.thumbnail.url)
- [Django]-Reducing Django Memory Usage. Low hanging fruit?
- [Django]-Getting Values of QuerySet in Django
- [Django]-Sending an SMS to a Cellphone using Django
0👍
Check you settings.py
media settings.
I had same error and found that:
MEDIA_URL = ‘/media/’
did the trick.
Before i only had:
MEDIA_URL = ‘media/’
- [Django]-CSRF Failed: CSRF token missing or incorrect
- [Django]-Django FileField with upload_to determined at runtime
- [Django]-Django removing object from ManyToMany relationship
0👍
In my case, override to_representation method works right.
# models.py
class DailyLove(models.Model):
content = models.CharField(max_length=1000)
pic = models.FileField(upload_to='upload/api/media/DailyLove/')
date = models.DateTimeField(auto_created=True)
def __str__(self):
return str(self.date)
# serializers.py
class DailyLoveSerializer(serializers.HyperlinkedModelSerializer):
def to_representation(self, instance):
representation = super(DailyLoveSerializer, self).to_representation(instance)
representation['pic_url'] = self.context['request'].build_absolute_uri('/' + instance.pic.url)
return representation
class Meta:
model = DailyLove
fields = '__all__'
# views.py
class DailyLoveViewSet(viewsets.ModelViewSet):
queryset = DailyLove.objects.all().order_by('-date')
serializer_class = DailyLoveSerializer
# result
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[
{
"url": "http://localhost:8088/daily/3/",
"date": "2019-05-04T12:33:00+08:00",
"content": "123",
"pic": "http://localhost:8088/daily/upload/api/media/DailyLove/nitish-meena-37745-unsplash.jpg",
"pic_url": "http://localhost:8088/upload/api/media/DailyLove/nitish-meena-37745-unsplash.jpg"
}
]
- [Django]-Django – is not a registered namespace
- [Django]-How to automatically run tests when there's any change in my project (Django)?
- [Django]-How to convert a Django QuerySet to a list?
0👍
check this!
class FileFieldWithLinkRepresentation(serializers.FileField):
def to_representation(self, value):
return create_link(value.url, self.context['request'])
and create_link
method:
def create_link(path: str, request: Request):
domain = request.META['HTTP_HOST']
if not path.startswith('/', 0, 1):
path = '/' + path
return request.scheme + "://" + domain + path
you can use FileFieldWithLinkRepresentation
in every class that needs hyperlink
representation of a FileField
.
- [Django]-How can I display a Django admin inline model within a fieldset?
- [Django]-ValueError: Related model u'app.model' cannot be resolved
- [Django]-Usage of .to_representation() and .to_internal_value in django-rest-framework?