I have a JavaScript file referenced on a django template:
<script src="{% static 'js/login.js' %} "></script>
I made some changes to that js file. Then, I refresh the page and I can't see the changes happen.
If I remove the JavaScript from the file and put it in the HTML, it works correctly, but if I try to do it using the external js file then it doesn't. I have tried closing the server and running runserver several times, I've also tried changing from Firefox to Chrome. It makes no sense at all. Please help me understand, I can get away with including all the js inside the HTML but it bothers me that I can't do it the normal way anymore.
More details about this error (the #$&%# weirdest thing I've found):
The JavaScript is something like this:
old_sentence = "Dig that hole, forget the sun" // this is what I want to change
$("#jqselector").text(old_sentence)
new_sentence = "Run, rabbit, run" // this is the new sentence, it just won't show up.
So, I changed the js and restart the server, still the html shows the old sentence. Then I deleted the reference to the login.js file and put all the js inside script tags in the HTML, of course, the new sentence appears. Then I include the login.js file, comment out the js inside the html but I delete all the content inside the login.js file, making it an empty file... but the old sentence still shows up.
Therefore the old login.js file must be cashed somewhere I don't know. Then I open Chrome and try it all again, same problem.
What can it be? is there an option to force django to refresh staticfiles? I thought restarting the server was enough. Should I reboot my computer?
Clearing static file python manage.py collectstatic --noinput --clear. This will clear the statics beforehand.
Clear the browser cache
Add a random string after the js file include, e.g jquery.js?rand=23423423, with each load.
It sounds like both your browsers have the javascript file cached. In Chrome you can clear the cache by pressing Ctrl + Shift + Del and ticking just 'Cached images and files'. Firefox probably has a similar shortcut.
You can take a look at this question on tips to disable caching of static files on your development server altogether.
You need to bust the browser cache. This template tag will output a time based uuid when DEBUG=True. Otherwise it will look for a PROJECT_VERSION environment variable. If that is not found it will output a static version number.
import os
import uuid
from django import template
from django.conf import settings
register = template.Library()
#register.simple_tag(name='cache_bust')
def cache_bust():
if settings.DEBUG:
version = uuid.uuid1()
else:
version = os.environ.get('PROJECT_VERSION')
if version is None:
version = '1'
return '__v__={version}'.format(version=version)
You would use in a template like this:
{% load cache_bust %}
<link rel="stylesheet" href="{% static "css/project.css" %}?{% cache_bust %}"/>
and here is the resulting output:
<link rel="stylesheet" href="/static/css/project.css?__v__=7d88de4e-7258-11e7-95a7-0242ac130005"/>
"Changes of staticfiles is not working". There can be multiple reasons for that.
Your browser is storing cache of your static files.
Solution (1): Open Incognito/Private window
Solution (2): Use hard refresh:
For mac: cmd + shift + r
For others: ctr + shift + r
If you're facing this issue in production then follow the steps below:
Remove staticfiles folder by following command:
sudo rm -rf staticfiles [inside your project directory]
Now run collectstatic command: python3 manage.py collectstatic
Restart gunicorn, by following command: sudo systemctl restart gunicorn
Restart nginx, by following command: sudo systemctl restart nginx
Sometimes browser stores thes staticfiles data (as caches) for a certain time. After couple of hours the problem may gone.
Hope this will fix you issue.
Instead of using complicated solutions you can add extra parameter to your includes in the templates.
For static includes:
<script src="{% static 'js/polls/polls.js' %}?version=1"></script>
For direct includes:
<link rel="stylesheet" type="text/css" href="/site_media/css/style.css?version=1" />
Note the ?version=1 in the code. Every time you're modifying the css/js file, change this version in the template, so browser will be forced to reload the file.
And if you want to avoid caching at all for some unknown reason, you may use the current timestamp instead of version:
<link rel="stylesheet" type="text/css" href="/site_media/css/style.css?{% now "U" %}" />
I have also struggled with this problem for hours. I have tried to inject random string using Javascript, but this method seems stupid and ugly-looking. One possible way to handle this problem is to introduce a custom tag. See this document for details:
Specifically, you need to create a package called templatetags in whatever apps you have created (or create a new one if you want). And you create any file in this package, and write something like this:
from django import template
from django.utils.crypto import get_random_string
from django.templatetags import static
register = template.Library()
class StaticExtraNode(static.StaticNode):
def render(self, context):
return super().render(context) + '?v=' + get_random_string(32)
#register.tag('static_no_cache')
def do_static_extra(parser, token):
return StaticExtraNode.handle_token(parser, token)
def static_extra(path):
return StaticExtraNode.handle_simple(path)
then you can use tag {% static_no_cache '.../.../path...' %} to create a path with random arguments!
I hope this would help!
One solution is to change the settings to the following:
STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.ManifestStaticFilesStorage'
What this does is create a copy of the static file with a content hash in the file name (when running collectstatic). This way when the contents are changed the filename is changed and the old cache won't be used. The only problem with this is it doesn't get used when in DEBUG = True mode so you have to do a shift-reload to do a hard reload.
You can read the docs on ManifestStaticFilesStorage for more info.
EDIT: I found a solution for making sure static files are not cached in dev and posted it on another question.
For me after re collecting the static files Just Changes reflected for me.
$ python manage.py collectstatic --noinput --clear
Now run your server, hope it works.
$ python manage.py runserver
A simple way to get rid, do a hard refresh cmd+shift+r/ctr+shift+r
A hard refresh is a way of clearing the browser’s cache for a specific page, to force it to load the most recent version of a page.
on browser cmd+shift+r/ctr+shift+r
Simply running python manage.py collectstatic should do the trick. Then hard refresh browser with ctrl + F5 which should work on all browsers.
first run python manage.py collectstatic --link -l then python manage.py collectstatic do not use python manage.py collectstatic --noinput --clear it will bring down your server.
To refresh static files you should run python manage.py collectstatic again.
If nothing else works, search for the file name in the project and look for an unexpected copy. If you saved to the wrong location (different app) at some point, or splintered off a new app from an old, load priority may be playing tricks on you.
If you don't want to refresh the browser cache each time you change your CSS and JavaScript files, or while styling images, you need to set STATIC_URLdynamically with a varying path component. With the dynamically changing URL, whenever the code is updated, the visitor's browser will force loading of all-new uncached static files. In this recipe, we will set a dynamic path for STATIC_URL using time of last edit in os.
import os
from datetime import datetime
def get_file_changeset(absolute_path):
timestamp = max(map(lambda x: os.path.getmtime(x[0]), os.walk(os.path.join(absolute_path, 'static'))))
try:
timestamp = datetime.utcfromtimestamp(int(timestamp))
except ValueError:
return ""
changeset = timestamp.strftime('%Y%m%d%H%M%S')
return changeset
And next change in your SETTINGS:
from utils.misc import get_file_changeset
STATIC_URL = "/static/%s/" % get_file_changeset(BASE_DIR)
How it works:
The get_file_changeset()function takes the absolute_path directory as a parameter and calls the os.path.getmtime() to each file in each nested directory and finds the last-edited file (with its max edit time). The timestamp is parsed; converted to a string consisting of year, month, day, hour, minutes, and seconds; returned; and included in the definition of STATIC_URL.
Note: With this you have to reload dev server each time when you edit your static files.
I was chasing a css static file change tonight. Going thru a Django tutorial.
My Django html page would not show the updated css to my base.css file.
I would see the original base.css but no my update to file.This is on a dev environment.
I did not think django cached static on dev and only after running coll ecstatic in production.
For a quick work around I changed the name of my test sites. base.css file to base1.css and the html page link to base1.css
reloaded page and my updated css took affect. No best solution. but quick fix.
For a window user, ctrl+f5 does the job on a development server and if this doesn't work then using the command python manage.py collectstatic is working else other ways mentioned in some answers are really risky so it's better to have a backup of your static files.
Private Tab works for me. That's why we should use private tabs at the time of development
Your browser will cache images and files (javascript included). First, clear just your cached images and files. Then use incognito mode in chrome or private browsing in firefox while you are making changes to your .js files so you see them instantly after a page refresh
Related
How can I correct the basic html display I get when I load the Django admin page, just as shown in the snapshot attached?
This is because your static files aren't set up properly. Typically Django's development runserver will take care of this for you, but in production, you need to run python manage.py collectstatic after ensuring your static files settings are correct: https://docs.djangoproject.com/en/1.11/howto/static-files/#configuring-static-files
Good luck!
I am deploying my django project under a subdirectory of my site, e.g.
http://example.com/apps/[django urls]
The problem is when I run collectstatic, a particular plugin I am using (dajaxice) uses the {% url %} tag to create the appropriate javascript code. Since collectstatic doesn't know about the deployment subpath, the reverse lookup is to the root url instead of the subpath. For example, it should be:
/apps/dajaxice/my_func
instead of:
/dajaxice/my_func
Is there a good way to change the way collectstatic does the reverse url without hacking the plugin? The only thing I can think of is to have one url specification for collectstatic that includes the 'apps' subpath and another one that does not for everything else. However, I cannot figure out how to change the settings.py when using collectstatic only. Any suggestions or alternative solutions?
I finally found how to solve this problem. Dajaxice provides a setting to change the url prefix:
DAJAXICE_MEDIA_PREFIX = 'dajaxice'
By defining this setting, to include 'apps' in the subpath, we can get the url we need. The problem is this prefix must only be altered in the collectstatic command and not when serving a webpage. Therein is the rub.
The solution is to create another settings.py file, we'll call it settings_cli.py. It will look like:
from settings import *
DAJAXICE_MEDIA_PREFIX = 'apps/dajaxice'
Next, we must load the new settings file when executing commands only by changing our manage.py file. Line 6 will now read:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MYPROJ.settings_cli")
where it formally refered to "MYPROJ.settings".
Now, when we run:
python manage.py collectstatic
it will use our special prefix, but not affect the normal prefix needed when serving webpages.
For more info on mulitple settings files, a good reference is http://www.djangobook.com/en/2.0/chapter12.html
I'm using django-compressor to concatenate and compress my CSS and JS files on this site. I'm serving static files from an S3 bucket.
On my local copy of the site, using a different S3 bucket, this all works perfectly. But on the live site, hosted on Heroku, it all works except the relative URLs for images in the CSS files do not get re-written.
eg, this line in the CSS file:
background-image: url("../img/glyphicons-halflings-grey.png");
gets rewritten to:
background-image:url('https://my-dev-bucket-name.s3.amazonaws.com/static/img/glyphicons-halflings-grey.png')
on my development site, but isn't touched on the live site. So the live site ends up looking in pepysdiary.s3.amazonaws.com/static/CACHE/img/ for the images (as it's relative to the new, compressed CSS file).
For now, I've put a directory at that location containing the images, but I can't work out why there's this difference. Both sites have this in their settings:
COMPRESS_CSS_FILTERS = [
# Creates absolute urls from relative ones.
'compressor.filters.css_default.CssAbsoluteFilter',
# CSS minimizer.
'compressor.filters.cssmin.CSSMinFilter'
]
And the CSS files are being minimised just fine... but it's like the other filter isn't being applied on the live site.
I recently ran into this issue on heroku, and running the latest version of django-compressor (1.3) does not solve the problem. I will provide the solution that I am using, as well as an explanation of the problems I ran into along the way.
The solution
I created my own 'CssAbsoluteFilter' that removes the settings.DEBUG check from the 'find' method like this:
# compress_filters.py
from compressor.filters.css_default import CssAbsoluteFilter
from compressor.utils import staticfiles
class CustomCssAbsoluteFilter(CssAbsoluteFilter):
def find(self, basename):
# The line below is the original line. I removed settings.DEBUG.
# if settings.DEBUG and basename and staticfiles.finders:
if basename and staticfiles.finders:
return staticfiles.finders.find(basename)
# settings.py
COMPRESS_CSS_FILTERS = [
# 'compressor.filters.css_default.CssAbsoluteFilter',
'app.compress_filters.CustomCssAbsoluteFilter',
'compressor.filters.cssmin.CSSMinFilter',
]
The absolute urls now always work for me whether DEBUG = True or False.
The Problem
The issue is connected to 'compressor.filters.css_default.CssAbsoluteFilter', your DEBUG setting, and the fact that heroku has a read-only file system and overwrites your app files every time you deploy.
The reason compress works correctly on your development server is because CssAbsoluteFilter will always find your static files when DEBUG = True, even if you never run 'collectstatic'. It looks for them in STATICFILES_DIRS.
When DEBUG = False on your production server, CssAbsoluteFilter assumes that static files have already been collected into your COMPRESS_ROOT and won't apply the absolute filter if it can't find the files.
Jerdez, django-compressor's author, explains it like this:
the CssAbsoluteFilter works with DEBUG = False if you've successfully provided the files to work with. During development compressors uses the staticfiles finder as a convenience so you don't have to run collectstatic all the time.
Now for heroku. Even though you are storing your static files on S3, you need to also store them on heroku (using CachedS3BotoStorage). Since heroku is a read-only file system, the only way to do this is to let heroku collect your static files automatically during deployment (see https://devcenter.heroku.com/articles/django-assets).
In my experience, running 'heroku run python manage.py collectstatic --noinput' manually or even in your Procfile will upload the files to S3, but it will NOT save the files to your STATIC_ROOT directory (which compressor uses by default as the COMPRESS_ROOT). You can confirm that your static files have been collected on heroku using 'heroku run ls path/to/collected'.
If your files have been collected on heroku successfully, you should be able to compress your files successfully as well, without the solution I provided above.
However, it seems heroku will only collect static files if you have made changes to your static files since your last deploy. If no changes have been made to your static files, you will see something like "0 of 250 static files copied". This is a problem because heroku completely replaces your app contents when you deploy, so you lose whatever static files were previously collected in COMPRESS_ROOT/STATIC_ROOT. If you try to compress your files after the collected files no longer exist on heroku and DEBUG = False, the CssAbsoluteFilter will not replace the relative urls with absolute urls.
My solution above avoids the heroku problem altogether, and replaces relative css urls with absolute urls even when DEBUG = False.
Hopefully other people will find this information helpful as well.
I've had this exact same problem for a month now, but this is fixed in the 1.3 release (3/18/13, so you were probably on 1.2), so just upgrade:
pip install -U django-compressor
The exact problem I gave up on working out, but it's related to Heroku and CssAbsoluteFilter being called but failing at _converter method. Looking at the 1.3 changelog, the only related commit is this: https://github.com/jezdez/django_compressor/commit/8254f8d707f517ab154ad0d6d77dfc1ac292bf41
I gave up there, life's too short.
Meanwhile this has been fixed in django-compressor 1.6. From the changelog:
Apply CssAbsoluteFilter to precompiled css even when compression is disabled
i.e. the absolute filter is run even with DEBUG = True.
I wanted to start playing around with Django again (I'm not an expert in Python/Django, but I can make nice things work tho). I used Mezzanine once just to see how it worked. The 'mezzanine-project myproject' command worked like a charm as I had a nice small app running quickly. So, today I downloaded the new Mezzanine 1.3 along with Django 1.4.3 and all its dependencies (pillow, pytz, html5lib, etc) and tried to create another project so I could now work on it in a more consistent manner for personal purposes.
For my surprise, when I ran the server, I got lots of 404 errors pointing to missing /static/ files. Also, after creating the database (with manage.py createdb command), the only thing created was the static folder containing only the pictures of the predefined gallery that come along with Mezzanine. Also, there is no Log in or signup buttons as well.
I've tried making a clean install of all Python and its site-packages with the same result. I also tried copying/pasting the folders containing missing files from the /site-packages/mezzanine folder into my project, but the result was just reducing the number of 404 messages.
I've been doing an extensive research on this issue (with no luck but maybe because of the release being recent?) and even trying to contact someone on the Mezzanine IRC channel with no success.
I hope I'm not missing something silly. Do I have to change anything (note that I'm ok with the old mezzanine default settings) in my settings.py or in a specific file before running manage.py createdb command?
For the record: before running createdb, The only thing I edited was settings.py and changed the database parameters to make it work with my MySQL Server and commenting the local_settings configuration as I do not need it.
Some parameters that could be of help:
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(PROJECT_ROOT, STATIC_URL.strip("/"))
By default, DEBUG is set to False in settings.py, and DEBUG is set to True in local_setting.py
Given that, if you just commented out importing local_settings.py, DEBUG would be False.
Django's development server won't serve static files when DEBUG is set to False, see the staticfiles section of the Django docs for more details.
First of all apologies for my earlier post which I accidently submitted before finishing the question... I'm not spamming :)
This seems to be a source of much confusion judging by the amount of similar titles on the subject, however after reading everything I could find on static files with the django development server i've almost given up hope!
So my static files are served from C:/Users/Dan/seminarWebsite/static/, in which i have sub folders for images, css etc. For simplicity lets just say I want an image to show on my website homepage (an easy task I would have hoped!)
SETTINGS:
STATIC_ROOT = 'C:/Users/Dan/seminarWebsite/static/'
STATIC_URL = '/static/'
The static files app is also active.
URLS:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
TEMPLATE: "{{ STATIC_URL }}images/vision.jpeg"
However only a broken link appears and at this address: http://127.0.0.1:8000/homepage/images/vision.jpeg; and i don't think it should be at that address (homepage is the url name of the page the staic image file is being called to)
Any help would be fantastic as its grinding my project to a hault.
Thank you
The url for your file should be http://127.0.0.1:8000/static/images/vision.jpeg
If your template has the following:
TEMPLATE: "{{ STATIC_URL }}images/vision.jpeg"
That means STATIC_URL isn't showing anything, which means you're probably not using RequestContext or you don't have the static context processor.
When debugging things like this, make sure you actually look in the template for what URL is being generated.
https://docs.djangoproject.com/en/dev/ref/templates/api/#subclassing-context-requestcontext
Check in your settings if DEBUG = False. If False - the built-in server will not serve static files unless you force it to do so with:
django-admin.py runserver --insecure
Here is a link to django docs about the The staticfiles app
--insecure
Use the --insecure option to force serving of static files with the
staticfiles app even if the DEBUG setting is False. By using this you
acknowledge the fact that it's grossly inefficient and probably
insecure. This is only intended for local development, should never be
used in production and is only available if the staticfiles app is in
your project's INSTALLED_APPS setting.
Finally worked! Everyones advice was very helpful thank you. For some reason I had a static subdirectory in my static directory and Django was looking in that...
Static
-Admin
-CSS
-Images
:Vision.jpeg
-....
-Static
-Admin
-CSS
-Images
:Vision.jpeg
http://127.0.0.1:8000/static/static/images/vision.jpeg
Don't really understand why but it works so thank you though