In Django, how can I use project wide static files? - django

At the moment I have
myproject/app1
And I am adding a second app in and I wish to share some common JS and CSS
I have moved my static files from
myproject/app1/static
to
myproject/static
What configuration changes do I have to make for the applications to recognize the new location? I don't remember ever setting the directory initially I think it just worked out of the box

From Django [1.11] Docs:
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.
Add to settings.py:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
Assuming you are using django.contrib.staticfiles app.

In settings.py, declare the following:
STATIC_URL = '/static/'
Also, add django.contrib.staticfiles to your INSTALLED_APPS if it isn't already.

Related

Why Django 4.0 can access static files only with STATICFILES_DIRS, not STATIC_ROOT

When I use STATIC_ROOT:
STATIC_ROOT = BASE_DIR / 'static'
Django cannot access static files and always return 404 error for them.
But when I use STATICFILES_DIRS:
STATICFILES_DIRS = [
BASE_DIR / "static",
]
Everything works well. What's the issue?
I don't understand why Django works in this way, I always thought that STATIC_ROOT is correct way of creating route.
STATIC_ROOT is where the collectstatic command will copy all the static files in.
This folder is meant for production use. So that all the static files in your project (from your apps, or third party apps etc.) are kept in a single folder and therefore becomes easy to serve in production.
By default, Django automatically searches for static files inside each app directory (this is helpful in writing reusable apps). The STATICFILES_DIRS setting allows you to define extra places to look for the static files.
Also, the STATIC_ROOT folder and the STATICFILES_DIRS folder should not be the same values.

Using static folding inside app folding Django

I have a static directory inside my apps folder. I added this line of code to my projects settings.py file
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
'/var/www/static/',
]
The file continues to result in a 404 not found. I'm getting stuck, what should I do?
It probably isn't mistake in your static files settings. But to be sure the relevant settings for static folder in app directories is STATICFILES_FINDERS https://docs.djangoproject.com/en/2.1/ref/settings/#staticfiles-finders. But the AppDirectoriesFinder should be present by default so it is probably OK.
Your problem is probably in your URL scheme:
For development purposes make sure you have django.contrib.staticfiles in your installed apps, DEBUG = True and STATIC_URL = '/static/' (or something similar). Then you should be able access the files.
For deploying it is more complicated but essentially you have setup STATIC_ROOT, before starting the server run python manage.py collectstatic command which will copy all static files to one location and then setup your server (Nginx) to serve the files from this folder under /static/ URL. Here is the official documentation https://docs.djangoproject.com/en/2.1/howto/static-files/#deployment
Note: if your app is foo and you have bar file in your static directory under foo app the URL for the file will be /static/foo/bar.

Django load static in development directly from static folder (Not from apps)

I use django for the backend, in the frontend I use vue.js, so 99% of my CSS it's handled by vue.js, however I need a simple base.css for some customization in the landingpage and few things like this.
Normally in django I would put the file inside app/static/app/base.css then do collectstatic and get it under static/app/ for production.
I would like to avoid to keep it under an app as it's just a file. I'm trying adding a folder under my main "static" folder. But it seems in development django in not fetching it at all, it fetches directly and only static files from apps.
How can I tell django to fetch it directly from the static main folder as it would do in production?
i.e. I want to add a folder called main in my root (where manage.py is) and use only that to store my static files for both production and development, without passing through the single apps.
You can tell Django to look for static files in other directories by using STATICFILES_DIRS settings.
Just add the following code in your settings.py and it should work:
STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]

Setting up django static directory for testing/development

In production, the apache server can handle serving static files just fine. For testing on my local machine I'm using manage.py runserver.
It seems the django apps I have somehow inject some default search paths into this debug server. The browser url shows everything under /static/whatever, but those files are coming from all over the place. This is fine for testing but when moving to production I'll need them in the one path. Thankfully, manage.py collectstatic provides a handy method to copy everything to the one directory given by STATIC_ROOT in settings.py. I've set mine to os.path.join(BASE_DIR, 'static/') where BASE_DIR is where manage.py is.
Now I want to start adding my own stuff in static, but everything's still being hosted by these hidden search directories provided by apps under DEBUG=True. I've tried the following in urls.py:
from django.conf import settings
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
if settings.DEBUG:
urlpatterns += staticfiles_urlpatterns()
and
import re
from django.conf import settings
if settings.DEBUG:
static_url = re.escape(settings.STATIC_URL.lstrip('/'))
urlpatterns += patterns('',
(r'^%s(?P<path>.*)$' % static_url, 'django.views.static.serve', {'document_root': settings.STATIC_ROOT}),
)
Neither have worked.
I tried providing my static directory in STATICFILES_DIRS, but get the error ImproperlyConfigured: The STATICFILES_DIRS setting should not contain the STATIC_ROOT setting. So then I tried removing my STATIC_ROOT so the path was only given in STATICFILES_DIRS. Finally I can access my files in development (still with staticfiles_urlpatterns from above).
However, I'm pretty sure removing STATIC_ROOT is not the right way to go about it. For a start, I won't be able to run collectstatic after installing other apps without manually changing everything around again. How should I be configuring my static directory for development?
Also, is there a way to turn off hosting app specific static directories so I can make sure my single static is set up correctly (but still be in development mode)?
You're making this more complex than it needs to be. Include "static" in STATICFILES_DIRS as you are doing, for the project-level assets, but make STATIC_ROOT - ie the destination of the collectstatic command - something else, probably "staticfiles", and alias that directory to /static/ in Apache. Django will serve your assets from STATICFILES_DIRS automatically, without you even needing to add the urlpatterns.
OK, I completely missed the point here.
STATIC_ROOT is for collectstatic to pool all the static content for you. You don't add your files to here because it gets overwritten.
Now for production you can get your webserver to host the directory STATIC_ROOT and point STATIC_URL to the url it can be found through the webserver.
STATICFILES_DIRS allows you to add your own directories for collectstatic to search and pool to STATIC_ROOT. Then you can nicely separate static stuff for each of your apps and/or a common project static.
For dev, django expects everything to be in STATICFILES_DIRS and hosts that, not STATIC_ROOT because then there would be duplicates. This makes sense for larger projects because you want to be working on the per-app files, not some blob of stuff for a website.

Django Static Files Development

This seems to be a source of much confusion judging by the amount of similar titles on the subject, however trying 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.
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 static image file is being called to).
Based on what you've posted so far, it looks like you're following the docs for django.contrib.staticfiles. I agree that the docs can be difficult to follow especially if one is new to django.
I believe the confusion stems from the fact that django.contrib.staticfiles has two modes of operation:
During the development phase where the development server is used, it dynamically searches for static files in predefined directories and make it available on STATIC_URL
For deployment, it assists in collating static files to a single directory (defined using STATIC_ROOT) so that the static files can be hosted using a webserver suited for static files. This collation is done using python ./manage.py collectstatic.
Here's a quick summary of how to get up and running. I haven't had a chance to try it out so there may be mistakes. Hopefully this will help you get started and at the very least help you understand the docs. When in doubt, do refer to the docs.
Hosting static files on the development server
Make sure you have 'django.contrib.staticfiles' in INSTALLED_APPS
Specify STATIC_URL. This will be the path where your static files will be hosted on.
STATIC_URL = '/static/'
Make sure your files are in the correct directories. By default, staticfiles will look for files within the static/ directory of each installed app, as well as in directories defined in STATICFILES_DIRS. (This behaviour depends on backends listed in STATICFILES_FINDERS).
In your case, you'd probably want to specify your directory in STATICFILES_DIRS:
STATICFILES_DIRS = (
'C:/Users/Dan/seminarWebsite/static/',
)
Make the view accessible by adding the following to the end of urls.py:
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
urlpatterns += staticfiles_urlpatterns()
Make sure you have DEBUG = True in settings.py.
That's it.
If you run your dev server (./manage.py runserver), you should be able to access your file via http://localhost:8000/static/images/vision.jpeg (which serves C:/Users/Dan/seminarWebsite/static/images/vision/jpeg).
Linking to static files in your templates
There are two ways to get a correct link for your static files - using the staticfiles template tag, and making STATIC_URL accessible to your templates. Since you've attempted the latter, we'll stick to that.
Make sure you have 'django.core.context_processors.static' in TEMPLATE_CONTEXT_PROCESSORS. If you haven't redefined TEMPLATE_CONTEXT_PROCESSORS then there is nothing to do since it should be there by default.
Make sure you use RequestContext when rendering your template. Example:
from django.template import RequestContext
# ...
def some_view(request):
# ...
return render_to_response('my_template.html', {
"foo" : "bar", # other context
}, context_instance = RequestContext(request))
You should now be able to use the following in your my_template.html:
<a href="{{ STATIC_URL }}images/vision.jpeg" />
Hosting static files on production server.
If all the static files you need to serve are store in that one directory (C:/Users/Dan/seminarWebsite/static), then you're almost there. Simple configure your webserver to host that directory on /static/ (or whatever you set STATIC_URL to) and you're good to go.
If you have files scattered in different directories and/or app specific static files, then you'll need to collate them.
Set STATIC_ROOT to the directory where you want to store the collated files.
Run ./manage.py collectstatic to do the collation.
Configure your webserver to host the that directory (STATIC_ROOT) on /static/ (or whatever you set STATIC_URL to).