Django staticfiles with cache busting - django

I'm trying to migrate my project from using {% compress %} to grunt for the whole front-end workflow. I got my grunt setup correctly and I can generate my main.min.css and main.min.js. With collectstatic I see them copied to the right folder, but when I deploy to staging all I get is a big fat 500 error.
INSTALLED_APPS = (
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.staticfiles',
'captcha',
'core',
)
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
STATICFILES_FINDERS = (
"django.contrib.staticfiles.finders.FileSystemFinder",
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
"compressor.finders.CompressorFinder",
)
and in the template:
<link rel="stylesheet" href="{% static "core/dist/css/main.min.css" %}" />
It works locally if I set DEBUG=False in settings.py (without loading the static files obviously). Any idea?

For everyone ending up here in the future: check your .gitignore file and be sure to only reference existing files in the template!
In my case I had dist/ in my .gitignore and I was storing my static files in core/dist/ so they got gitignored and ended up not being on the server.

Related

Local development Django static files coming from library directory rather than my project

I have a Django (3.1) app that I've set up to serve static files, that is, myapp/settings.py has
DEBUG = True
.
.
.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'myapp',
.
.
.
]
.
.
.
STATIC_URL = '/static/'
STATIC_ROOT = 'static/'
But instead of serving files from the static directory of myapp, it's serving static files from /Library/Python/3.7/site-packages/django/contrib/admin/static/. I have tested this by adding files to both directories,
~/Projects/myapp/static/file-from-project.js
/Library/Python/3.7/site-packages/django/contrib/admin/static/file-from-library.js
and then
python3 manage.py runserver
with a template including the lines
<script src="{% static 'file-from-project.js' %}"></script>
<script src="{% static 'file-from-library.js' %}"></script>
and file-from-library.js loads fine but I get a 404 for file-from-project.js. What am I doing wrong here?
Directory structure with the referenced files:
myapp
/myapp
settings.py
.
.
.
/static
file-from-project.js
.
.
.
/templates
.
.
.
manage.py
.
.
.
OK, I see the problem I think.
STATIC_ROOT is an absolute path, not a relative one. if you set it to eg. BASE_DIR / "static" you might get what you want.
I usually set BASE_DIR at the top of my settings.py as it gets used for a few things:
BASE_DIR = Path(__file__).resolve(strict=True).parent.parent
The other thing is that you have DEBUG=True which means it's going to be looking at your STATIC_URL under your app dirs. If you move the file to:
~/Projects/myapp/static/app_folder/file-from-project.js
It should work :)
Edit: I noticed myapp is an app, and not the project name, which makes me wonder what the project is called.
Your static files for development for this structure should probably be in:
~/Projects/myapp/static/myapp/<static file>
When you deploy, obviously DEBUG should be False, but here you should run collectstatic in order to gather all the static files in one place for deployment.

Django + Sass + Compressor: loading cached css files, unable to update or remove

Aloha!
I have been working on a django project and recently switched to SASS for styling. The initial compiling on the css file seemed to work fine, but once I went to update the file I noticed the changes were not reflected in the browser.
Upon further investigation, I have determined the issue is a cached file located at static/CACHE/css/output.ad5d8929a444.css however I am unable to find this file anywhere in the filesystem, and running commands such
./manage.py compilescss --remove
./manage.py collectstatic
does not resolve the issue.
I have tried looking around for other questions and it seems this question is most closely related however that suggestion did not work in my case.
I have tried deleting all browser data and I typically only use incognito mode in Chrome for development anyways as to avoid caching files in the first place.
I have tried searching for the file inside of my filesystem, however, it seems I am unable to locate the statice/CACHE folder.
My question is how do I force django to use the new css file, and where do I find the cache folder?
This is my first time using SASS for styling, so any advice in that department is appreciated.
Settings.py
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, '/my_portfolio/my_portfolio/static/')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'my_portfolio/static'),
]
STATICFILES_FINDERS = [
'compressor.finders.CompressorFinder',
]
MEDIA_ROOT = os.path.join(BASE_DIR, 'my_portfolio/img')
MEDIA_URL = '/img/'
#SASS
STATIC_FILES_FINDERS = [
'compressor.finders.CompressorFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'sass_processor.finders.CssFinder',
]
# SASS_PROCESSOR_INCLUDE_DIRS = [
# os.path.join(BASE_DIR, 'my_portfolio/static/my_portfolio'),
# ]
SASS_PROCESSOR_ROOT = os.path.join(PROJECT_ROOT, 'static')
COMPRESS_PRECOMPILERS = (
('text/x-scss', 'django_libsass.SassCompiler'),
)
COMPRESS_ENABLED= True
base.html
{% load static %}
{% load sass_tags %}
{% load compress %}
{% compress css %}
<link rel="stylesheet" href="{% sass_src 'my_portfolio/stylesheet.scss' %}" type='text/css'>
{% endcompress %}
If you need any further information please let me know and I will update the question accordingly.
Thank you for any and all tips or advice you can provide!
Your browser may have cached the stylesheet. Clear your browser's cache and reload the page and see if it changes.

Django runserver not serving some static files

My local testing server for Django v1.8.2 on Windows 8.1 is only serving certain static files. Others are giving a 404 error.
#urls.py - excerpt
urlpatterns = [
url(r'^$', views.index)
] + staticfiles_urlpatterns()
#settings.py - excerpt
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'main',
'users'
)
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
As far as I can tell the development server is configured to serve static files. When running runserver I get no warnings, and my code displays no syntax errors (import statements do exist and so forth). I did for testing purposes run collectstatic before starting the server just to be sure at least once.
My view template is:
{% load staticfiles %}
<img src="{% static 'main/img/ComingSoon.jpg' %}" alt="Coming Soon">
The link generated is /static/main/img/ComingSoon.jpg which looks correct, the file does exist in that location. What perplexes me is that this directory produces a 404 error, but other static files are served. The directory hierarchy is:
static/
admin/
css/
..
js/
..
img/
..
main/
img/
ComingSoon.jpg
The URL localhost:8000/static/admin/img/ gives an expected message about indexes being not allowed. However, localhost:8000/static/main/img/ reports \main\img\ cannot be found. Both are 404 statuses. Images within static/admin/img/ do display correctly with the same links as what is giving an error. The Administration site for Django does display correctly.
Why would one directory within static/ not be indexed or accessible?
According to the Django documentation regarding static/:
This should be an initially empty destination directory for collecting
your static files from their permanent locations into one directory
for ease of deployment; it is not a place to store your static files
permanently. You should do that in directories that will be found by
staticfiles’s finders, which by default, are 'static/' app
sub-directories and any directories you include in STATICFILES_DIRS).
I moved the files to another directory such as:
myApp/
main/
static/
main/
img/
..
static/
..
After running collectstatic I noticed the script created the subdirectories in myApp/static/ as expected and it must have generated the URLs needed because it now properly serves the files.

Azure local emulator does not serve django static files correctly

I have followed the Django / Visual Studio / Azure tutorial http://www.windowsazure.com/en-us/develop/python/tutorials/django-with-visual-studio/. I have a very simple application, basically one simple html template with one javascript and one css file (code examples at the end).
When I run the code in the local debugger, everything works fine. When I try to run the code in the local Azure emulator with default VS and Azure SDK provided settings, I get the html file as response for both the javascript and css requests. For example, request for /static/calculator.js returns the application's html template instead of calculator.js.
What could cause this behavior and how could this be fixed?
UPDATE:
It seems that as I run the website in Azure emulator, any url on the emulator host 127.0.0.2 will return the "main page", that is, the only view defined in views.py. For example, 127.0.0.2/ returns the webpage (as it should), and so does 127.0.0.2/nonexistenturl. My hunch is that this is somehow due to misconfiguration of either fastcgi or IIS express as used by Azure emulator. What would be good starting points for trying to fix this problem?
Code examples:
Html template links:
<link rel="stylesheet" type="text/css" href="/static/calculator.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="/static/calculator.js"></script>
urls.py:
urlpatterns = patterns('',
url(r'^$', 'ExamCalculator.Calculator.views.main_page'),
)
in settings.py staticfiles related settings should be correct:
STATIC_ROOT = 'C:/.../static/'
STATIC_URL = '/static/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
...
)

Static files get deployed from STATICFILES_DIRS, but not STATIC_ROOT

I have problems with deploying files in my development environment.
See my configuration below.
python manage.py collectstatic collects all files from '/Users/vikingosegundo/Projects/website/media/' as expected and stores them at /Users/vikingosegundo/Projects/website/mydjangoproject/static/.
But although the links to the css files are correct when using <link href="{% static "css/style.css"%}" rel="stylesheet" type="text/css"> (rendered as <link href="/staticmedia/css/style.css" rel="stylesheet" type="text/css">), the originals files at /Users/vikingosegundo/Projects/website/media/ will be deployed, not from the STATIC_ROOT /Users/vikingosegundo/Projects/website/mydjangoproject/static/.
Even if I delete the files that are in /Users/vikingosegundo/Projects/website/media/.
Where is my misconfiguration?
settings.py
MEDIA_ROOT = '/Users/vikingosegundo/Projects/website/mydjangoproject/media/'
MEDIA_URL = '/sitemedia/'
STATIC_ROOT = '/Users/vikingosegundo/Projects/website/mydjangoproject/static/'
STATIC_URL = '/staticmedia/'
STATICFILES_DIRS = [
'/Users/vikingosegundo/Projects/website/media/',
]
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.debug',
'django.core.context_processors.i18n',
'django.core.context_processors.media',
'django.core.context_processors.static',
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
#....
)
I think, this is because the serving of static files using the django build-in views and helpers is intended for development and debugging purposes only. When DEBUG is True in your project settings, your static files are served from their original location. This helps to avoid being forced to run the collectstatics management command every time you for example change your CSS files.
When you switch your DEBUG setting off, django.conf.urls.static.static and its cousins helpers will stop working, since they are intended for development purposes only. Still, the template tags will work, since they must point to the correct static file urls in either production or development.
Running the collectstatic management command is a convenient helper for copying your static files to their final destination (STATIC_URL), where serving them in a production environment is your own responsibility. This is best done by an (static) web server location (avoiding pumping them through the django/python process), and thus Django's docs explicitly recommend to not use Django for static file serving.
See Managing static files: Serving static files in development for more about serving static files in development.