Django cms project for OpenShift. Where to place static files? - django

I am working on a django-cms based web site but having trouble with the static files. As I am going to deploy the site to OpenShift, I have used the django-example to construct the site (https://github.com/openshift/django-example). This way I ended up with the following overall structure of my django project:
root_folder
wsgi
media
static
my_project
my_app
templates
So as you see, it's a bit different from the standard Django dir structure. Django docs (https://docs.djangoproject.com/en/1.8/howto/static-files/) has told me the following:
Include django.contrib.staticfiles in INSTALLED_APPS: Done
Define a static url, e.g. STATIC_URL = '/static/‘: Done
Use static template tag to refer to static files, e.g. {% static "my_app/myexample.jpg" %}: Done
Furthermore, the static root is defined as
STATIC_ROOT = os.path.join(WSGI_DIR, 'static')
where WSGI_DIR points to the folder named wsgi.
I keep getting 404s in my dev environment where I use Debug=True, when I try to refer to the static files from my base template. I have tried to place them in the following locations with no luck:
/wsgi/static/
/wsgi/static/my_app/
/wsgi/my_project/static/
/wsgi/my_project/static/my_app/
/wsgi/my_project/my_app/static/
/wsgi/my_project/my_app/static/my_app/
Where should I place the static files, and have I configured it correctly?

I discovered that my_app was not in the INSTALLED_APPS list (apparently this is not part of the code structure I got from django-example). When I added the app to the list, it worked. The correct location of the static files: /wsgi/my_project/my_app/static/my_app/

Related

custom static files not loading in django project

I have a django project where I have kept all the static files in a project level static directory.
I have included
STATIC_URL = "/static/"
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
in the settings.py. ALso I have added + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) to the urlpatterns in the project level urls.py.
My issue is that some of the static files load whereas some do not. For. eg. I am using django_google_maps and the (example url) http://127.0.0.1:8000/static/django_google_maps/js/google-maps-admin.js loads right and the corresponding work is done.
But when I try to load my custom js/css/any-static files, (example url http://127.0.0.1:8000/static/images/favicons/favicon.ico or http://127.0.0.1:8000/static/js/image-upload-script.js), they do not load and raise a django.views.static.serve error with 404 not found.
They are right there in the directory though. I see that the static files used by third party packages are loading right but not my custom ones.
What is it that I am missing? Do we require something else to load our custom js/css files?? And yes I have used {% load static %} in my template.
I had been using static files at the project level and not the app level. Any new static file, I was directly adding to the static directory which was my static root as well. Now as per this answer,
https://stackoverflow.com/a/12161409/5379191 ,
"Your STATIC_ROOT directory should be empty and all static files should be collected into that directory (i.e., it should not already contain static files)".
So, the main thing was that it should not already contain the static files.
I created a new staticfiles folder in the project level directory, shifted my custom static files to that directory, ran the collectstatic command, and then boom it worked.
So, the main thing here to remember is not to directly place your static files in the static root dircetory but rather let the collectstatic do its job.
Adding this worked for me:
MEDIA_URL = '/static/images/'

recommended location for static & templates directories

I am a little bit confused about the recommended location of the templates and static directories. Apparently it is better to have 1 templates directory in every app folder. Django automatically look for templates there. However it seems not to be the case for static, is it? Can I tell django to look for static within the directory of the app currently running (instead of a single directory in the root folder)?
Thanks.
you can manually setting django to look where static files are.
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"), # basic, noqa.
os.path.join(BASE_DIR, "blog/other_static"), # another static folder in blog app
)
Django will look those folders.
and one more, you may set your static folder like static/blog/js/some.js and static/otherapp/css/some_css.css.
You may make folder in static directory named same as your app.
And I'm not suggest managing your static files in your app directory unless you're going to use your app as reusable.

Order of finding static files and templates in django-apps

For example I have 2 apps in my django project with templates and static files with identical subpath:
app1 /
static /
style.css
templates /
index.html
app2 /
static /
style.css
templates /
index.html
than, in settings.py I added this two apps:
INSTALLED_APPS = (
'app1',
'app2',
)
now I use in some way 'style.css' and 'index.html' in templates, e.g.
{% include 'index.html' %}
so, question is:
Does Django guarantee that when I reference to 'style.css' or 'index.html' will be used files from app2 subdirectories?
Is it any other way to point Django preferable variants of files in such situation?
As per documentation, first match wins:
Duplicate file names are by default resolved in a similar way to how
template resolution works: the file that is first found in one of the
specified locations will be used.
https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#django-admin-collectstatic
Now, when you tell Django to collect static files or render templates, Django asks special "finders" in order they are defined in your configuraiton for specified resource.
Default order for static files is "FileSystemFinder" that searches STATICFILES_DIRS in order they are added in it. If FileSystemFinder fails to find file in those dirs, Django uses next finder set, the "AppDirectoriesFinder" that searches in "static" subdirectories in your apps directories.
Same mechanic is applied to templates. When you tell Django to render "index.html", it first asks "filesystem.Loader" find template named like that in directories defined in TEMPLATE_DIRS. If search fails, Django asks next template loader, "app_directories.Loader" that searches template dirs in applications "templates" subdirs.
To answer your question, because app1 is registered before app2, Django will use it's style.css and index.html instead of ones coming from app2. If you want to change this behaviour, put app2 above app1 in your installed apps setting.
Documentation:
https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.loaders.app_directories.Loader

Static file cannot be found in Django view

I am having an issue with static files in the development server on Django 1.5.4. I am not sure if it is the same problem on the actual production server (running Apache), as I found a solution for that which works at the moment (simply hard coding the full URL - I know it's bad, but it gets the job done).
I am using Reportlab to create a PDF file for my project, and I need to include a picture on that. I followed the answer in a different post:
from django.templatetags.static import static
url = static('x.jpg')
Unfortunately, the answer I get from the server is an IO Error: 'Cannot open resource "localhost:8000/static/images/x.jpg"', even though a copy and paste of that into the URL bar clearly shows me that the picture is exactly there.
My settings regarding static files are the following, and they do work for everything else (CSS, Javascript, etc):
ROOT_PROJECT = os.path.join(os.path.split(__file__)[0], "..")
STATIC_ROOT = os.path.join(ROOT_PROJECT, 'static')
STATICFILES_DIRS = ()
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
Thanks for your help!
Make sure that django.contrib.staticfiles is included in your INSTALLED_APPS.
There are usually a couple of ways to store static files.
One way is to create a static folder inside your app folder and store the files there. You can check that here:
Is to create a folder and store your static files which are not for any particular app.
From the django documentation:
Your project will probably also have static assets that aren’t tied to a particular app. In addition to using a static/ directory inside your apps, you can define a list of directories (STATICFILES_DIRS) in your settings file where Django will also look for static files.
For example:
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "static"),
'/var/www/static/',
)
If you are into production then check production deployment for more details!

Django and staticfiles questions

The more I learn Django, the more I discover new things.
I read the official docs, stackoverflow and google but I still have doubts.
What's the correct/normal way to organize our static files?
I mean folders and settings.py
I have something like:
CURRENT_PATH = os.path.dirname(__file__)
STATIC_ROOT = os.path.join(CURRENT_PATH, 'static')
STATIC_URL = '/static/'
Ok, Im going to collect all my apps statics on ~/static/
I created a static/appname folder on every app and I put all my app's static there.
Also, I need a static folder to project-wide statics (what's the common name for it? Since I used /static/ for collected stuff and they cannot be equal).
So far so good, I have css like:
href="{{ STATIC_URL }}appname/styles.css"
and it works like charm.
But I think that when I deploy my app, I have to run 'collectstatic' so I put that '/static/' folder serving on Cherokee.
The question is... will that work? I tried commenting the AppDirectoryFinder and the _DIRS one and that doesn't work on local (Having the static stuff collected, I mean, the css on /static/ and in the other folders too).
Is just better to have one static folder on root for all the project? And copy the admin css to that folder (AKA manually collectstatic).
The projects I see on github/bitbucket are ready to be deployed, I need to know the steps to go from dev to deploy.
Thanks!
I'll break this down as I use the django static app
url at which your static media will be served
STATIC_URL = '/static/'
this is used for 2 things
{{STATIC_URL}} in your templates and the static file url
and for hosting your static files in django (DEVELOPMENT ONLY)
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
The location at which your files reside on the server
STATIC_ROOT = '/var/www/website/static'
this is used when you run collectstatic and is where your webserver should be looking
your file finder definition
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
I've used the default from django you can of course use more but here is the crux of what you are looking to know
'django.contrib.staticfiles.finders.AppDirectoriesFinder'
will find any folder named "static" that is inside an installed app
'django.contrib.staticfiles.finders.FileSystemFinder'
will tell django to look at STATICFILES_DIRS (this is your project wide static files)
which should be defined as a tuple
STATICFILES_DIRS = (
join( CURRENT_PATH, 'static' ),
)
where 'static' is whatever you want and you can add in as many other folders to monitor as you wish.
the sub directories you place inside each app ie:app/static/appname are not necessary but will ensure that files of the same name inside different apps don't overwrite files from other apps or your root static folders
all of this was taken from my own experience and https://docs.djangoproject.com/en/1.3/ref/contrib/staticfiles/
Also, I need a static folder to project-wide statics (what's the common name for it? Since I used /static/ for collected stuff and they cannot be equal).
Are you sure? I'm pretty sure I'm using the same folder to collect my static files and to hold my project-wide static files. Not sure if that's not recommended pracice, but it works for me.
Note that this is just on the deployment side; my codebase just has the project static files.