matteok
matteok

Reputation: 2199

Django ImageField url slow when using Amazon s3

In my Django Application currently running on Heroku I noticed that retrieving url's from ImageFields takes forever when hosting on s3. The application is written using Django Rest Framework. When I try to retrieve a list of objects that have image fields the response is so slow Heroku throws a timeout error. I assume this is because boto has to retrieve a url from s3 for each individual ImageField upon each request. How can I speed up the process to prevent these timeout errors?

Upvotes: 5

Views: 1591

Answers (3)

Alexey
Alexey

Reputation: 1438

I've faced similar problem, what I decided to do is to change this:

class SomeModelSerilazier(serializers.ModelSerializer):

    png_icon = serializers.SerializerMethodField()
    ...

    def get_png_icon(self, some_model_obj):
        return some_model_obj.png_icon.url

to this:

    def get_png_icon(self, some_model_obj):
        return str(some_model_obj.png_icon)

surprisingly, its working ~ 15 times faster on my machine.

Upvotes: 1

Gagik Sukiasyan
Gagik Sukiasyan

Reputation: 856

One of solution was provided by xyers above. Here is other possible solution I used for my project. You can define the MEDIA_URL variable in settings.py file of your django project:

MEDIA_URL = 'https://%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME

Then you can use this variable when you need to access to URL. For example if you have model:

class MyModel(...):
    image = FileField(...)

Then you can get URL of that file as follows:

mymodel = MyModel.objects.get(...)
image_url = os.path.join(settings.MEDIA_URL, mymodel.image.name)

Upvotes: 1

xyres
xyres

Reputation: 21799

You can create a new field in your models, for example, image_url.

class YourModel(...):
    image_url = models.CharField(...)
    # other fields

When the image is uploaded/saved the first time, retrieve its URL and populate image_url field with this value. You'll need to save your model again, though.

You can use this value later when required.

Demerits

This may lead to unnecessary database lookups. If, however, you use Memcached or something like that to cache database, I wouldn't worry.

Upvotes: 1

Related Questions