简体   繁体   中英

Django 1.10 media (FileField) 404

My first question ever, so go easy. I'll give as much detail as possible.

My setup

  • django 1.10 (I know, I need to upgrade)
  • python 3.5.[something]
  • postgres DB
  • gunicorn
  • nginx

The problem and what I've tried

The problem is that I pulled a recent commit that was working fine locally and suddenly none of a model's images, which previously rendered fine, are working - I'm getting 404s for all of them. I've tried the following:

  • Checking out previous commits
  • Restarting gunicorn ( sudo systemctl restart gunicorn )
  • Restarting nginx
  • Restarting postgresql
  • Using python manage.py shell to access objects and check that they're still associating with a URL to the file

My code works when run locally - none of the uploaded images/files are causing 404s. As with my production environment, the logos folder sits in the main directory of my project, rather than being appended to a media folder (which other answers and the django docs suggested would be the case - this could be a red herring though).

My browser console shows the 404s and that it's trying to fetch from <domain.com>/media/logos/<filename> , even though they're stored (I've checked the file structure) in <project_folder>/logos/<filename> (ie without the media folder), but this was never previously a problem. Again, locally this is also the case but is completely fine.

My code and stuff

In my models.py I have this field:

class Thing(models.Model):
    ...
    logo = models.FileField(upload_to='logos/', blank=True)

...which I then render in my HTML file with:

<img class="..." src="{{ thing.logo.url }}>

...which, again, is how django docs says to do it (rather than hard-coding a URL). I read in the docs that the file is stored as part of the object in the database, so referring to a filepath with filename wouldn't necessarily work (or something similar), therefore that this is the best option.

As far as I can see my urls are set up fine:

urlpatterns = [
...
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

...as per this answer (and probably others).

In settings.py no filepaths or URLs are hard-coded: they're all relative to the os.path... .

MEDIA_URL = '/media/' and MEDIA_ROOT is unset (default is '')

I can't think of any other information that would be helpful, but if there is then let me know. Please help! I currently have a live website with ugly alt-text :(

The static(...) only works in development. In production you should configure your server (eg Apache or Nginx) to serve the files. See the example for Apache and modwsgi. – Alasdair Jan 9 at 22:12

Thanks @Alasdair for your above comment - unfortunately I can't mark it as the answer, but it led to it.

I hadn't setup Nginx to handle media files - only static files. So my Nginx conf file now looks like this:

location /static/ {
    root /home/<path>/<to>/<folder>;
}

location /media/ {
    root /home/<path>/<to>/<folder>;
}

My Django app was then uploading files to a slightly unexpected location, so I had to copy those files across to the correct media file location and set that right.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM