I am using Whitenoise to serve static files (images, css, js) for a Django site. Now my problem is that the static files seem to be "cached to much"(?) when working locally. Description of actions:
Initially my static files are served correctly
I edit a file in static/
I run ./manage.py collectstatic (which correctly identifies one updated file).
When going to http://127.0.0.1:8000/ my browser consistently shows the old stale version of the file. I have even tried completely removing the generated staticfiles/ folder - and the browser still seems to be able to dig out an old version of the file?
This is when running locally in debug mode. Do not have a consistent understanding of how it is in production, but I think it works better (as it should?) there.
My configuration:
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
....
INSTALLED_APPS = [
# My apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
...
...
STATIC_URL = 'static/'
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_DIRS = [
("js" , BASE_DIR / "static/js"),
("css" , BASE_DIR / "static/css"),
("img" , BASE_DIR / "static/img")
]
I guess the problem is that I do not really understand the Whitenoise model - slightly frustrating as this should be quite simple??
Update: I have tested this in Firefox with Ctrl-Shift R to reload the page, and got the old version. But when actually deleting the browser cache explicitly things work. feels a bit excessive that I have to manually wipe the browser history - but I can live with that.
If a hard reload works, then the browser is most likely caching the parent request (rendered html result).
So if you have an endpoint, /myendpoint/, that returns a rendered template, where the template contains the static file reference handled by whitenoise , css/mycss.{hash}.css, the parent request is being cached and the browser doesn't see the updated static file reference.
Django has some tools that help dealing with browser-side caching.
https://docs.djangoproject.com/en/3.2/topics/cache/#controlling-cache-using-other-headers
If you want to make sure the client always get's the latest page you can use the never_cache decorator.
from django.views.decorators.cache import never_cache
#never_cache
def myview(request):
...
Related
I'm new to Django and i've seen a lot of people asking about this particular problem but i followed every instruction i could find and it still doesn't work.
My directorys look like this:
/Peperina
/Writing
/statics/writing
/css
/scss
/js
forms.js
/templates/writing
forms.html
my setings.py:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
(...)
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'writing.apps.WritingConfig',
]
(...)
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
STATIC_URL = '/statics/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'statics'),
)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
My urls.py:
(...)
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
finaly my forms.html
(...)
{% load static %}
<script src="{% static 'writing\js\forms.js' %}"></script>
yet 404 keeps showing up
Try to change your STATIC_ROOT to os.path.join(BASE_DIR, 'statics') ?
I have had this same problem multiple times myself.
I'd first start by removing the "writing" directory, and move all folders up.
You won't need to change your settings.py file too much if you start by doing that.
Create a new directory, called "static_root" in the same level as your current "statics" folder and copy all the static files you've got in your statics folder over to there. Be sure to have two copies of each (one in "statics" and another in "static_root"). This will be explained shortly.
Your static file information in settings.py should now be changed to look like this:
STATIC_ROOT = os.path.join(BASE_DIR, 'statics')
STATIC_URL = '/statics/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static_root'),
)
The reason you need to have a separate static_root is because Django sometimes gets a bit funny about there being a root static folder and a normal static folder. More info can be found here.
I personally do not have STATICFILES_FINDERS in my settings.py, so test with removing that.
Maybe also try running Python manage.py collectstatic as this will collect the static files for you.
If none of this works, as you mention you are new to Django, I'd recommend following some tutorials from start to finish to see if you can get it to work.
E.g. start here if you haven't done already.
Well this turned up to be a pretty goofy solution but i changed the name of all my "statics" directorys to just "static" and then did the same thing in my settings and... it worked
So... thanks anyway
Hello and thanks for your help in advance. I realize this question has been asked and answered in other placed but none of those answers are working for me.
I am new to python and django and have inherited a small webapp. I have a dev environment working on my computer with mostly unchanged code, the only changes being to the database name and password to point to my local mySQL server.
However, when I run the app, everything works except for the static files. I'm getting 404s in the console when trying to retrieve static files and js methods in static are coming up undefined.
The BASE_PATH, STATIC_URL, STATIC_ROOT, STATICFILES_DIR, STATICFILES_FINDERS are all unchanged from the currently working production code, and as far as my beginner eyes can tell are configured correctly according to the documentation and the multiple answers to this question.
Is there something that could be different about what I have installed on my computer that would be causing this? Why else would it be different between production and my local copy? Is there something I have to run to get this working?
Some settings in settings.py:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
INSTALLED_APPS = [
'biogen.apps.BiogenConfig',
'msm.apps.MsmConfig',
'tracker.apps.TrackerConfig',
'accounts.apps.AccountsConfig',
'process_manager.apps.ProcessManagerConfig',
'process.apps.ProcessConfig',
'pfd.apps.PfdConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'djangobower',
'rest_framework',
'crispy_forms',
'django_summernote'
]
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIR = [
os.path.join(BASE_DIR, 'components/static'),
]
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'djangobower.finders.BowerFinder',
]
Included in the templates:
{% load static %}
Thanks again in advance...
Provide something like this:
Consider you have in your project root directory static_files as a source and static as a destination of your static files - you initially place and edit them in static_files (or any other you have):
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static_files'),
os.path.join(BASE_DIR, 'static_files/js'),
os.path.join(BASE_DIR, 'static_files/html'),)
STATIC_ROOT = os.path.join(BASE_DIR, 'static', )
STATIC_URL = '/static/'
Notice it's STATICFILES_DIRS, not STATICFILES_DIR
Then run
python manage.py collectstatic
to collect your static files from static_files to static
Turns out I needed to load all the static files from Bower. All these files are present on production but not on development for some reason!
Try running
python manage.py collectstatic
Autocomplete is not working for static files for me with Django 2.0.
I'm using static files in my project with the current structure
project
-app_1
-templates
--base.html
-static
--bootstrap
---bootstrap.min.cs
---bootstrap.min.js
Here's the HTML code where autocomplete doesn't work. Am I doing something wrong?
The files are linked properly and I'm getting the bootstrap design, the problem is that the autocomplete isn't working.
Here's my static settings
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(os.path.join(BASE_DIR, 'static')),
)
I've been able to resolve this on two different computers and projects in two different ways.
The first project uses settings module instead of a single file like this
settings
- init.py
- shared.py
- prod.py
- dev.py
Autocomplete for static started working after I set the proper path to settings like this:
In the second instance I had a settings.py file and autocomplete started working when I replaced my AppConfig with app name in settings INSTALLED_APPS like this, though I'm inclined to think this is just some kind of bug:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'depapp', # Used to be depapp.apps.DepappConfig
]
Did you mark the directory as "Resource"?
I'm working with Django and I'm using a AdminLTE framework for the estilização, but, when I turn the DEBUG to False, the page shows with pure html.
DEBUG = True:
DEBUG = False:
settings.py:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'saga.core',
'saga.subjects',
'saga.accounts',
'saga.tasks',
'saga.study_time',
'django_adminlte',
'django_adminlte_theme',
]
django_adminlte and django_adminlte_theme are the apps for the style framework.
When DEBUG = True Django will serve static and media files. When DEBUG = False it will not. Therefore all of the js and css files will return a 404 error unless served. For a better of understanding of what is going on i would recommend reading https://docs.djangoproject.com/en/1.11/howto/static-files/ These static files may also be present in installed apps and not just within the project itself.
For local testing you can add the following to your urls.py urlpatterns:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
static can be imported from from django.conf.urls.static import static
Further information can be found at https://docs.djangoproject.com/en/1.11/howto/static-files/#serving-files-uploaded-by-a-user-during-development
Further information regarding how to deploy static files in production can be found at https://docs.djangoproject.com/en/1.11/howto/static-files/deployment/
I want to use static files to load my css with runserver command. The problem is that i tried all the solution i found here on stackoverflow and also in django docs, but it doesnt works at all... I dont know what can i do...
If i set
STATIC_URL = '/static/'
STATIC_ROOT = 'C:\Users\Max\Works\www\mysite\mysite\static'
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
)
I thought it was enough... Am i missing something?
Can you tell me what is the best setting for have static files in develompent envirnoment?
Thanks in advice...
EDIT(1)
I already putted in my template {{ STATIC_URL }}css/dark-grey.css" and ofc the css is in C:\Users\Max\Works\www\mysite\mysite\static\css\dark-grey.css, i really can't get what is wrong...
Use / slashes and NOT \ slashes in the path, even for windows paths.
In your settings.py
DEBUG=True
As per the docs:
This view is automatically enabled by runserver (with a DEBUG setting
set to True).
Using the URL pattern is a way to force it, which I personally don't even have to do in my project as long as DEBUG=True. You would always have DEBUG on when you are developing, and when you switch to production you aren't even using the development server anyways, so you would be pointing your production server to the static location.
This is a snippet of my static settings from my settings.py. I do not manually have to add that static view URL
import os
DEBUG = True
PROJECT_ROOT = os.path.dirname( __file__ )
PROJECT_NAME = os.path.basename(PROJECT_ROOT)
STATIC_ROOT = os.path.join(PROJECT_ROOT, '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.
os.path.join(PROJECT_ROOT, 'web/'),
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
TEMPLATE_CONTEXT_PROCESSORS = (
...
'django.core.context_processors.static',
...
...
)
You need to add url patterns:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
# ... the rest of your URLconf here ...
urlpatterns += staticfiles_urlpatterns()
See the documentation here
You also need to run the following command to get the static files moved into the right place (and for Django to know they're there):
python manage.py collectstatic
Full documentation on static files in Django 1.3 is here:
https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/