Django static images aren't displayed - django

I have deployed one of my project with free version in 'pythonanywhere', but the static images aren't visible in there.
While testing in local everything seems to be working but on deploying and adding static images to it, the images aren't visible there. Please help me find what went wrong here.
In my django templates I used these tags to show images
<div class="card-image">
<img src="{{cat.category_image.get_photo_url }}">
</div>
Or provide me some documentation links to have a look into development issues.

The documentation for django static files in production is here.
Make sure you run python manage.py collectstatic before you deploy as the local server stores static files in a separate location to the production server. Again, here's the documentation on the collectstatic function.

#Giles, cant add an image to the comment. Here is the screenshot from pythonanywhere

Related

Heroku's Django is not loading lity.css and lity.js

I am trying to use this simple lightbox for embedding a video on my Django project. Locally with:
python3 manage.py runserver
it runs fine. However, once deployed to Heroku the app struggles to find the css and the js of lity, though it is located in the correct folder. Has anyone run into a similar problem?
The project is live here:
https://dry-depths-69493.herokuapp.com/
And the git-repo is here:
https://github.com/Datenrausch/heroku
Looking at your code in github, I see that ... master/honoradar/static/honoradar/lity/ has no subfolder named dist, but your HTML looks for that subfolder.
Try changing these lines from index.html to the correct files (I'm not sure which are the correct ones)
<script src="{% static 'honoradar/lity/dist/lity.js'%}"></script>
<link rel="stylesheet" href="static/honoradar/lity/dist/lity.css">
or add a dist subfolder with the correct files.

How to correct Django server from loading basic html on web browser instead of standard html?

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!

Django won't refresh staticfiles

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

Using Grunt on Heroku for a Django app's static files

We'd like to use GruntJS (http://gruntjs.com/), a package we're familiar with, to minify JS and compile LESS to CSS (among other things) when we deploy our Django app to Heroku. Has anyone figured out a smart of doing this yet?
I wasn't able to find anything after a couple of hours of looking myself.
Try using django_compressor with COMPRESS_PRECOMPILERS settings.
COMPRESS_PRECOMPILERS = (
('text/less', 'lessc {infile} {outfile}'),
)
Template:
{% compress css %}
<link type="text/less" rel="stylesheet" href="/static/css/styles.less" charset="utf-8">
<style type="text/less">
#color: #4D926F;
#header {
color: #color;
}
</style>
{% endcompress %}
The django-grunt project looks promising. I haven't tried it myself yet, though - at first glance it doesn't seem to support the nice grunt development watch-server workflow for quicker development that you get in a Yeoman webapp (at least it's not documented on their README).
For my current open source project, I created a kind-of hacky solution that I'm still iterating on, but it does work:
I keep my static files and the base template as a normal Yeoman-scaffolded Grunt project in its own GitHub repo, using buildcontrol to export the built files in a separate branch for Heroku deployment
the Django app is a normally laid out Django app, with some script magic to link up the development or production versions of the frontend code into my static folders (I can keep grunt server running to quickly iterate on the frontend code)
to deploy to Heroku, I use a minimally-modified python buildpack that fetches the production branch of the frontend repo and links it up using the aforementioned script (I tried building it using grunt on Heroku, but it took ages to fetch all the npm dependencies every time, so I found buildcontrol to be much more efficient)
Update: I'm since iterating on making everything work in a single repo in this project.

Django css not rendering from amazon server- 304 not modified

I am using a amazon server to host my Django app. It used to work fine but after some changes in the css files the app is not rendering those files anymore. I ran python manage.py collectstatic. Through firebug I can see the css files through up the error 304 not modified.
I guess this post address the issue but I couldnt understand it! What should I do to make so that static files render properly?
It is good practice to use something like /path/to/style.css?ver=CURRENT_VERSION to ensure that all users get recent version of CSS, JS and other static. CURRENT_VERSION could even be auto-populated from current Git commit id on deploy.