0

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> (i.e. 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 :(

Digitiain
  • 23
  • 5
  • What are the values of yout `MEDIA_URL` and `MEDIA_ROOT` settings? – Alasdair Jan 09 '18 at 21:57
  • `MEDIA_URL = '/media/'` and I haven't set `MEDIA_ROOT`, as the default is blank. – Digitiain Jan 09 '18 at 22:02
  • The `static(...)` only works in development. In production you should configure your server (e.g. Apache or Nginx) to serve the files. See the [example for Apache and modwsgi](https://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/modwsgi/#serving-files). – Alasdair Jan 09 '18 at 22:12
  • It would be a good idea to set `MEDIA_ROOT` instead of using the empty string. Normally you would set it to a location outside of your project, since those files should not be checked in. – Alasdair Jan 09 '18 at 22:12
  • Would that affect whether or not I get 404s though? After all, it used to work without issue. I appreciate that it's best practice though @Alasdair – Digitiain Jan 09 '18 at 22:21
  • As I said, in production you should configure your server (e.g. Apache or Nginx) to serve the files. You haven't shown any configuration that would serve the files. Perhaps you had `DEBUG=True` before. – Alasdair Jan 09 '18 at 22:25
  • `DEBUG=False` and has done for a while. However, I have just checked Nginx config and `location /static/ ...` is set but not `location /media/ ...`. Do you think that's the problem? – Digitiain Jan 09 '18 at 22:44
  • Yes, that's the problem. You need to configure Nginx to serve the media files. – Alasdair Jan 09 '18 at 22:46
  • Still doesn't explain the change from it working before the most recent commit, but I'll check and report back. I'll also look into folder permissions issues, as I've seen [indications](https://www.digitalocean.com/community/questions/nginx-unable-to-server-static-and-media-images?answer=27666) that that could be an issue too. Thanks for your help so far! – Digitiain Jan 09 '18 at 22:51

1 Answers1

1

The static(...) only works in development. In production you should configure your server (e.g. 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.

Digitiain
  • 23
  • 5