I need a bit of clarification regarding how Django updates its static files. Here is a hypothetical that will explain my predicament:
I'm working on my own website which requires a link to a PDF that is stored as a static file.
Later I replaced this PDF file, with a slightly altered name, and made corrections respectively in my code.
Then I run the collectstatic command to replace the old static files and everything works as expected. Explorer shows me that the old files have been properly replaced in their respective folders.
When I go to test the link I'm still forwarded to my old PDF file. The old staticfile as if nothing has been replaced.
Can anyone explain to me how this happened? I'm just concerned and a bit freaked out that my old static file is still being referenced. I mean it could just be a simple typo or I have a haunted static folder on my hands.
When collectstatic command is run Django searches for present static files in STATICFILES_DIRS and copies them into STATIC_ROOT path.
The link to file that Django returns - is exactly how it is set in code - Django will not search it this file is present to show the link.
Check or search your code for old file name, maybe it is left somewhere.
Also, static files usually are css, js, images - files used in rendering page. User content, data files (PDF file looks to be one of these) for downloading via download link - should be served as MEDIA FILES.
Related
I am not able to locate my external javascript and css files when I ctrl click their path string.
My html template path is 'bodhitree-flipped/concept/templates/concept/content_developer.html'. And my external video.js file path is 'bodhitree-flipped/video/static/video-js/video.js'.
Any Idea how I make pycharm to locate my js files? I know the solution for this is to run python manage.py collectstatic command which will copy all my asset files to /staticfiles folder but I don't want to do it as it will increase the size of my project by duplicating all the static files.
I tried rebuiding the file index with option under File->invalidate caches/Restart... but unfortunately this also doesn't work.
This is how my project structure look like.
click on the file to see code in settings.py
Any help is deeply appreciated.
I have just changed the python template language from jinja to Django (settings->languages and framework->python template languages)and then invalidated the file cache. It worked.
I'm looking to do a bit of 3D modeling on my site and I'm trying to serve the requisite object (.obj) and material (.mtl) files via Django. When I put them into my static directory and run collectstatic, the .mtl files are found and collected just fine, but the .obj files are completely ignored.
Is there any way around this? Is there somewhere Django bans certain file types for static collection, and can that be overwritten? Thanks so much in advance!
Sorry, all - figured this out. Was a Git issue - I think I had some global .gitignore file that was ignoring .obj files, so I just created a new blank one. Closing issue.
I am packaging a Horizon Plugin. I have a bunch of templates, a view, as well as css, js files, and images.
Everything should be contained so that the package is either a .deb or a tarball. So right now I keep all files in /opt/stack/horizon/openstack_dashboard/dashboards/<my-dashboard-name>.
My question is, how do I include js and css files properly? There is /opt/stack/horizon/openstack_dashboard/settings.py file that specifies HORIZON_CONFIG.js_files, however it is always empty! I put a list of files there, it still comes out as empty in the templates. So the question is, how do I include js and css files in a Horizon dashboard plugin, for the purpose of packaging it in either a single tarball or a .deb package?
You should store static files below <my-dashboard-name>/static. It's best to namespace your static files, I use the following directory structure:
<my-dashboard-name>/static/<my-dashboard-name>/js and so on for css and img then I reference the files in the HTML templates with /static/<my-dashboard-name>/js/jsfile.js, that way you won't get any name collisions.
When someone uses your plugin they extract your dashboard and register it in the right places and then additionally they have to run the collectstatic django management command from the base openstack_dashboard directory (in your case /opt/stack/horizon/), either:
$ ./run_tests.sh -m collectstatic
or
$ ./manage.py collectstatic
That should copy your static files to the right places according to how the site has been configured.
Here's the scenario:
I'm running Django 1.3.1, utilizing staticfiles, and django-compressor (latest stable) to, among other things, compile LESS files.
I have an "assets" directory that's hooked into staticfiles with STATICFILES_DIRS (for project-wide static resources). In that directory I have a "css" directory and in that a "lib.less" file that contains LESS variables and mixins.
So the physical path is <project_root>/assets/css/lib.less and it's served at /static/css/lib.less.
In one of my apps' static directory, I have another LESS file that needs to import the one above. The physical path for that is <project_root>/myapp/static/myapp/css/file.less and it would be served at /static/myapp/css/file.less.
My first thought was:
#import "../../css/lib.less"
(i.e. based on the URL, go up to levels from /static/myapp/css to /static/, then traverse down into /static/css/lib.less).
However, that doesn't work, and I've tried just about every combination of URLs and physical paths I can think of and all of them give me FilterErrors in the template, resulting from not being able to find the file to import.
Anyone have any ideas what the actual import path should be?
After tracking down exactly where the error was coming from in the django-compressor source. It turns out to be directly passed from the shell. Which clued me into removing all the variables and literally just trying to get the lessc compiler to parse the file.
Turns out it wants a relative path from the source file to the file to be imported in terms of the physical filesystem path. So I had to back all the way out to my <project_root> and then reference assets/css/lib.less from there. The actual import that finally worked was:
#import "../../../../assets/css/lib.less"
What's very odd though is that lessc would not accept an absolute filesystem path (i.e. /path/to/project/assets/css/lib.less). I'm not sure why.
UPDATE (02/08/2012)
Had a complete "DUH" moment when I finally pushed my code to my staging environment and ran collectstatic. The #import path I was using worked fine in development because that was the physical path to the file then, but once collectstatic has done it's thing, everything is moved around and relative to <project_root>/static/.
I toyed with the idea of using symbolic links to try to match up the pre and post-collectstatic #import paths, but I decided that that was far too complicated and fragile in the long run.
SO... I broke down and moved all the LESS files together under <project_root>/assets/css/, and rationalized moving the LESS files out of the apps because since they're tied to a project-level file in order to function, they're inherently project-level themselves.
I'm sort of in the same bind and this is what I've come up with for the most recent versions of compressor and lessc to integrate with staticfiles. Hopefully this will help some other people out
As far as I can tell from experimenting, lessc doesn't have a notion of absolute or relative paths. Rather, it seems to maintain a search path, which includes the current directory, the containing directory of the less file, and whatever you pass to it via --include-path
so in my configuration for compressor I put
COMPRESS_PRECOMPILERS = (
('text/less', 'lessc --include-path=%s {infile} {outfile}' % STATIC_ROOT),
)
Say, after running collectstatic I have bootstrap living at
STATIC_ROOT/bootstrap/3.2.0/bootstrap.css.
Then from any less file, I can now write
#import (less, reference) "/bootstrap/3.2.0/bootstrap.css"
which allows me to use the bootstrap classes as less mixins in any of my less files!
Every time I update a less file, I have to run collectstatic to aggregate them in a local directory so that compressor can give less the right source files to work on. Otherwise, compressor handles everything smoothly. You can also use collectstatic -l to symlink, which means you only need to collect the files when you add a new one.
I'm considering implementing a management command to smooth out the development process that either subclasses runserver to call collectstatic each time the server is reloaded, or uses django.utils.autoreload directly to call collectstatic when things are updated.
Edit (2014/12/01): My approach as outlined above requires a local static root. I was using remote storage with offline compression in my production environment, so deployment requires a couple extra steps. In addition to calling collectstatic to sync the static files to the remote storage, I call collectstatic with different django config file that uses local storage. After I have collected the files locally, I can call 'compress', having configured it to upload the result files to remote storage, but look in local storage for source files.
I have a problem with my app here. My configuration is as such I can upload a new release and symbolically link it for production -- however, this means every time I upload a new release, all of the photos that were uploaded in any parts of my entire project are wrapped into the old release and disappear.
How can I save these files to a static file location which does not get wrapped in the release? Thanks in advance.
I guess best for this is keeping your media files out of your source project folder, you could eg have a structure like:
myproject
|
|----media
|----src
There's no need to have the media folder in the same directory as your source code, apps etc. So you have a solution where the dir with your release only contains static files! The same applies to the database, if you are using sqlite... Have a look at this for a more detailled structure!
Of course this no must, but experience shows it makes live much easier!