# Struggling with file upload and serving in production

**URL:** <https://forum.djangoproject.com/t/struggling-with-file-upload-and-serving-in-production/5513>\
**Category:** Using Django\
**Created:** [December 2, 2020, 12:54pm UTC](https://forum.djangoproject.com/t/struggling-with-file-upload-and-serving-in-production/5513 "2020-12-02T12:54:43Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![BenBausch](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/benbausch/32/2677_2.png) [@BenBausch](https://forum.djangoproject.com/u/BenBausch)\
**Post date:** [December 2, 2020, 12:54pm UTC](https://forum.djangoproject.com/t/struggling-with-file-upload-and-serving-in-production/5513/1 "2020-12-02T12:54:43Z")

</div>

I have setup my python project using nginx and gunicorn as described in this tutorial [https://djangocentral.com/deploy-django-with-nginx-gunicorn-postgresql-and-lets-encrypt-ssl-on-ubuntu/](https://djangocentral.com/deploy-django-with-nginx-gunicorn-postgresql-and-lets-encrypt-ssl-on-ubuntu/)

so far everything works perfectly fine. My project is in /root/project\_folder/

I want to upload files via the admin page, but I get a bad request error 400. The media folder I want to add the files to is /var/www/my\_domain/media (owned by the group www-data). This is also properly configured since I can see the images when I move them manually into that folder.

Do you guys maybe have any idea why the issue may be ?

the main problem is when uploading I need to save the image to the media root:

/var/www/domain/media/images/dad/ProfilePicture/offline\_screen.png

But when I send request to view the image the web server returns the following:

/media/var/www/domain/media/images/dad/ProfilePicture/offline\_screen.png

The upload\_to path needs to be images/dad/ProfilePicture/offline\_screen.png for correct request but then the image is uploaded to the wrong folder

Any ideas ? Thanks in advance!

UPDATE:

Here is my nginx config `

```auto
server {
    server_name domain.net www.domain.net ip_address;

location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
    root /var/www/domain;
}

location = /media/ {
    root /var/www/domain;
}

location / {
    include proxy_params;
    proxy_pass http://unix:/var/log/gunicorn/domain.sock;
}

listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/domain/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/domain/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {

if ($host = www.domain) {
    return 301 https://$host$request_uri;
} # managed by Certbot

if ($host = domain) {
    return 301 https://$host$request_uri;
} # managed by Certbot

listen 80;
server_name domain www.domain ip_address;
return 404; # managed by Certbot
}

```

`

Here is my media root / media url:

```auto
MEDIA_ROOT = '/var/www/domain/media' #os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

```

The url.py:

```auto
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('webpages.urls')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
    urlpatterns += static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)

```

And finally how I serve and upload Images:

```auto
def get_path_of_content_image(instance, filename):
    return os.path.join(settings.MEDIA_ROOT, "images", str(instance.course.topic), str(instance.course), filename)

class Topic(models.Model):
title = models.CharField(max_length=100)
description = models.TextField(max_length=445)
image = models.ImageField(upload_to=get_topic_profile_path, default="images/default.jpeg")

def __str__ (self):
    return self.title

def image_tag(self):
    if self.image:
        return mark_safe('<img src="%s" style="width: 200px; height:200px;" />' % self.image.get_image())

def get_image(self):
    if self.image:
        return str(self.image.url).replace('/media/var/www/domain', '') ########1
    else:
        return settings.STATIC_ROOT + 'webpages/img/default.jpeg'

image_tag.short_description = 'Current Image'

```

I wrote this line #######1 since set the upload path to the full media root but then in order to return the correct path I need to remove the media root prefix. And also very importantly this only works if DEBUg set to TRUE.

---

<div class="post-metadata">

**Author:** ![CodenameTim](https://sea2.discourse-cdn.com/flex026/user_avatar/forum.djangoproject.com/codenametim/32/31507_2.png) [@CodenameTim](https://forum.djangoproject.com/u/CodenameTim)\
**Post date:** [December 3, 2020, 4:09pm UTC](https://forum.djangoproject.com/t/struggling-with-file-upload-and-serving-in-production/5513/2 "2020-12-03T16:09:57Z")

</div>

The path being stored in `Topic.image` is the relative path that gets appended to `MEDIA_ROOT` in the filesystem. Then when creating the urls, it assumes that component that serves the media files will also be serving files from that `MEDIA_ROOT` directory and only needs the relative path stored in `Topic.image`.

The code version of this answer is to remove `settings.MEDIA_ROOT` from your `upload_to` function.

```auto
def get_path_of_content_image(instance, filename):
    return os.path.join("images", str(instance.course.topic), str(instance.course), filename)

```
