Static files will be discovered in "apps" that you create (found in INSTALLED_APPS) or in additional directories that you specify in STATICFILES_DIRS.
Let's say I did:
django-admin.py startproject myproject
And then:
cd myproject
./manage.py startapp myapp
mkdir myapp/static
mkdir myproject/static
Would give you a directory structure that looks something like
/Users/me/develop/myproject/
> myapp/
> migrations/
> static/
> __init__.py
> admin.py
> models.py
> tests.py
> views.py
> myproject/
> static/
> __init__.py
> settings.py
> urls.py
> wsgi.py
> manage.py
And then in settings.py you add "myapp" to INSTALLED_APPS.
In this structure, myapp/static/ files will be automatically discovered by Django because it is an installed app with a static directory. However, myproject/static/ files will NOT be discovered automatically because "myproject" is not in INSTALLED_APPS (and it shouldn't be).
This is because of the default STATICFILES_FINDERS setting, which is:
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
'django.contrib.staticfiles.finders.FileSystemFinder',
]
The first finder, AppDirectoriesFinder, scans the directories of all of your INSTALLED_APPS, and discovers any "static" folders they might contain.
The second finder, FileSystemFinder, scans extra directories that you specify in STATICFILES_DIRS, which is an empty list by default.
So if you want those files in /Users/me/develop/myproject/myproject/static/ to be discovered (as you probably do), you can add this to your settings.py:
from os import pardir
from os.path import abspath, dirname, join
# Get the root directory of our project
BASE_DIR = abspath(join(dirname(__file__), pardir))
# Add our project static folder for discovery
STATICFILES_DIRS = (
# /Users/me/develop/myproject/myproject/static/
join(BASE_DIR, 'myproject', 'static'),
)
Now, all of this is separate from STATIC_ROOT, which is a place where all static files are copied when you run ./manage.py collectstatic. For projects just starting out, this is usually in the project root folder: /Users/develop/me/myproject/static/
So we would add, in settings.py:
# /Users/me/develop/myproject/static/
STATIC_ROOT = join(BASE_DIR, 'static')
But this is only really used in production—it's a way to compile all of your static assets into a single spot, and then point /static/ at it with your server (e.g. NGINX).
During development, you can skip collectstatic altogether, and have Django discover and serve your static assets on the fly. Django provides a "serve" view to do this in django.contrib.staticfiles.views.serve.
Try this in your urls.py:
from django.conf import settings
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.staticfiles.views import serve
admin.autodiscover()
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
]
if settings.DEBUG:
urlpatterns += [
url(r'^static/(?P<path>.*)$', serve),
]
In your example, you are asking Django to serve files from STATIC_ROOT, which is also fine, but requires you to run ./manage.py collectstatic first, and every time your static assets change—which can be a hassle.