Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ValueError at / Missing staticfiles manifest entry for ''

Tags:

django

I'm trying to migrate from Django 1.9.7 to Django 1.11.5. I have three different django apps, and they are pretty much the same regarding packages and settings. I have deployed all three of them to a web server and two apps are working without any problems, but third one gives me headache - i get this error all the time:

ValueError at / Missing staticfiles manifest entry for ''

Here are the most relevant settings from settings.py:

# -*- coding: utf-8 -*-
from settings import * 

SECRET_KEY = '***'

SITE_ID = 3

ALLOWED_HOSTS = [
    'localhost', 
    '127.0.0.1',
    '.example.com',
    '.example.com.',

    ]

INSTALLED_APPS += (
    'storages',
    'example',
    'example2',
    'el_pagination',
    'debug_toolbar',
)

ROOT_URLCONF = 'example.urls'

WSGI_APPLICATION = 'example.wsgi.application'

DEFAULT_FROM_EMAIL = '[email protected]'

MANAGERS = ADMINS

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
        'DEFAULT_MIDDLEWARE_ALIAS': 'default',
        'DEFAULT_MIDDLEWARE_SECONDS': '300',
        'DEFAULT_MIDDLEWARE_KEY_PREFIX': '',
    }
}

PASSWORD_HASHERS = (
    'django.contrib.auth.hashers.SHA1PasswordHasher',
)

#AWS_HEADERS = {  # see http://developer.yahoo.com/performance/rules.html#expires
#       'Expires': 'Thu, 31 Dec 2099 20:00:00 GMT',
#        'Cache-Control': 'max-age=94608000',
#S    }

# AMAZON S3 & CLOUDFRONT SERVING MEDIA FILES
AWS_S3_HOST = 's3.eu-central-1.amazonaws.com'
AWS_STORAGE_BUCKET_NAME = '***'
AWS_CLOUDFRONT_DOMAIN = '***.cloudfront.net'
AWS_ACCESS_KEY_ID = "***"
AWS_SECRET_ACCESS_KEY = "***"
MEDIAFILES_LOCATION = 'example/media'
MEDIA_ROOT = '/%s/' % MEDIAFILES_LOCATION
MEDIA_URL = '//%s/%s/' % (AWS_CLOUDFRONT_DOMAIN, MEDIAFILES_LOCATION)
DEFAULT_FILE_STORAGE = 'example.custom_storages.MediaStorage'

# WHITENOISE SERVING STATIC FILES
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
STATIC_ROOT = os.path.join(BASE_DIR, '***/static/example') 
STATIC_URL = '/static/'

I don't know why i'm getting this error because i did nothing different (while deploying) comparing to the other two apps which are working regularly. Settings are almost the same! I've also tried to empty .css files so i could throw away possibility that css files are somewhere pointing to files that doesn't exist, but it didn't help. I've updated all of the packages that my websites are using. This app is working normally under Django 1.9.7, but i can't make it to work under 1.11.5.

EDIT - HOW DID I FIX THIS?

Thanks to @evansd's answer i've managed to find the problem! In one of my templates i've had this code which messed the whole thing up:

{% for num in numbers  %}
<li>
   <img src="{% static ''%}img/header/{{num}}.jpg" alt="image {{num}}"/>
</li>
{% endfor %}

and i've changed it to:

{% for num in numbers  %}
<li>
   <img src="{% static 'img/header/'|addstr:num|addstr:'.jpg' %}" alt="image {{num}}">
</li>
{% endfor %}

After this fix everything works well! For custom addstr template tag look this answer.

like image 434
Ljubisa Livac Avatar asked Sep 28 '17 22:09

Ljubisa Livac


2 Answers

The problem is that somewhere in your templates you're referencing a static file that doesn't exist. Specifically, your passing an empty string to static. Perhaps you have a line like {% static some_variable %} where some_variable is undefined?

In Django 1.11 the behaviour changed so that errors are thrown on missing files. See: https://docs.djangoproject.com/en/1.11/ref/contrib/staticfiles/#django.contrib.staticfiles.storage.ManifestStaticFilesStorage.manifest_strict

If you fix this reference then everything should work.

like image 158
D. Evans Avatar answered Oct 09 '22 03:10

D. Evans


Not running following ( python manage.py collectstatic ) may be your issue.

Solution:

You can circumvent this issue and improve the code by moving the static() call out of the model field and changing the default value to the string "pledges/images/no-profile-photo.png". It should look like this:

avatar_url = models.URLField(default='pledges/images/no-profile-photo.png')

When you access avatar_url, use either

  1. (frontend / Django Templates option) {% static profile_instance.avatar_url %}, where profile_instance is a context variable referring to a Profile object.

  2. (backend / Python option) use static(profile_instance.avatar_url).

Explanation:

By using the result of static() for a default value, the app is putting a URL in the database that includes the STATIC_URL prefix -- which is like hard-coding it because data won't change when settings.py does. More generally, you shouldn't store the results of static() in the database at all.

If you ensure that you're using the {% static %} tag or static() function each time you're accessing avatar_url for display on the frontend, STATIC_URL will still be added based on your environment config at runtime.

This SO thread has a lot of good content on staticfiles

Why the error is happening:

It looks like you have a circular dependency:

  1. collectstatic needs to run in order to create manifest.json

  2. your application needs to load in order to run manage.py commands, which calls static()

  3. static() relies on an entry in manifest.json to resolve.

Source answer here. Django Model: ValueError: Missing staticfiles manifest entry for "file_name.ext"

like image 21
Ajeeb.K.P Avatar answered Oct 09 '22 03:10

Ajeeb.K.P