Serving user uploaded images in production

In my production environment, I have this settings defined in settings.py:

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')

User can add a product which has ImageField.
How can I use this uploaded image file in Django template ?

I tried this way but it does NOT work:

img src="{{ product.image.url }}" alt="">

But when I use {{ p.thumb_image.url }} in a <p> for example then it gives the path where image really is stored: /media/images/products/pic1.jpg

Some people says this must be added to urlpatterns

+ static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

but this is also not working for me. And for this I found in Django documentation it should not be used in production.

WHAT SHOULD I USE IN PRODUCTION ?

I believe almost every application accept user files uploads which then must be served somehow…

A production environment would host your static files on another sever. If you’re using AWS or Digital Ocean in production, they have “buckets” that your static files will be stored in. Django has a really nice third-party package that works very well with Digital Ocean and AWS static file storage.

Rather than trying to toss ideas out in the abstract, it would probably be more effective to get into the specifics - and this includes understanding the complete details of the environment in which you’re trying to do this, and what’s going wrong.

For example, you wrote:

What do you mean by this? What specifically is being rendered in the browser?

Also, what is your production environment? Is it self-hosted or service-hosted? What kind of web server are you running? (Apache? nginx?) How is Django itself being run? (uwsgi? gunicorn? something else?) All these factors are interrelated and part of the deployment process is understanding how all the pieces fit together.

Production deployment is a complex issue, with probably hundreds of combinations possible. There are no “standard generic answers” that are going to work in every situation.
For example, @Suttonium writes “A production environment would host your static files on another server.” But, I have never worked in that type of environment. I’ve deployed at least a dozen production environments and every single one co-hosts all static and media files on the same device.

@KenWhitesell you’re right, abstract is probably not the best way to reply, especially when dealing with a complex issue.

Whenever I answer questions, I tend to default to what I have used in the past and what I know works.

Here is the django article regarding static file hosting:

https://docs.djangoproject.com/en/3.1/howto/static-files/deployment/

It mentions that you can host static files on another server OR on the server that the rest of your code is hosted on, which makes perfect sense, especially because both tactics require the use of the collectstatic function.

Regarding hosting static files and assets on another server (or bucket), here is are some tools I have used to assist with the process in the past and from personal experience, I can say they work like a charm.

https://django-storages.readthedocs.io/en/latest/backends/amazon-S3.html

Production environment is Ubuntu server with Nginx and Gunicorn. I’m running multiple Django projects there.

When I added + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) to settings.py and set DEBUG = True then uploaded images in MEDIA were rendered fine, but when I set to DEBUG = False then it’s not server anymore.

What should I do ?

Should I use Nginx to server this folder or something else ?

Yes. When debug is off, Django will not serve static files. You need to configure nginx to serve files from those urls.

Another popular option if you don’t want to configure Nginx to serve static assets is to use the popular WhiteNoise app. http://whitenoise.evans.io/en/stable/

@KenWhitesell, @mblayman, @Suttonium - thank you for your answers - at the end I found out the solution is just in front of me all the time !!!

When I went to configure my NGINX I found out that I already HAVE the same configuration for static files (so the static files are not just working by itself as I thought - they are working because of this configuration line):

location /static/ { root /home/user1/myproject; }

So I just did the same for media files:

location /media/ { root /home/user1/myproject; }

And that’s it !!!

1 Like

Glad to see you figured it out! Now in the future, if you ever run across this issue again, you’ll know how to fix it :slight_smile:

1 Like

@pitagora04 i am facing a similar issue. I wanted to ask you what did you put in ‘upload_to’ in django models?

@Samar2170 I put something like upload_to='myproducts/images/'.
And files are then being uploaded into: myproject\media\myproducts\images

Hey, I’m suffering from the same problem but Im using apache server.
would you know to tell me what how to fix it?

@BenK93 unfortunately I don’t know apache. But I guess similar approach is needed, maybe someone else can help ?