Shihui Guo

How Django handles templates and static files for multiple applications?

Please note: this note is based on django 1.5

Say you got your project called MYPROJECT, and two applications: APPLE and BANANA in it. so your foler looks like:

├── APPLE
│   ├── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── BANANA
│   ├── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── manage.py
└── MYPROJECT
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py


First tip, put the templates and static files for each application inside each application folder, and the tree becomes like this:

├── APPLE
│   ├── __init__.py
│   ├── models.py
│   ├── static
│   ├── templates
│   ├── tests.py
│   └── views.py
├── BANANA
│   ├── __init__.py
│   ├── models.py
│   ├── static
│   ├── templates
│   ├── tests.py
│   └── views.py
├── manage.py
└── MYPROJECT
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

However before you dive into folder and put the static files directly there, use my second tip: use proper namespace, which basically mean:

├── APPLE
│   ├── __init__.py
│   ├── models.py
│   ├── static
│   │   └── APPLE
│   │       ├── css
│   │       ├── images
│   │       └── js
│   ├── templates
│   │   └── APPLE
│   ├── tests.py
│   └── views.py
├── BANANA
│   ├── __init__.py
│   ├── models.py
│   ├── static
│   │   └── BANANA
│   │       ├── css
│   │       ├── images
│   │       └── js
│   ├── templates
│   │   └── BANANA
│   ├── tests.py
│   └── views.py
├── manage.py
└── MYPROJECT
    ├── __init__.py
    ├── settings.py
    ├── urls.py
    └── wsgi.py

Because we added another level, so in your views.py for each application (take APPLE as example), you need to add this additional level as well:

def index(request):
    # This is correct
    return  render(request, 'APPLE/index.html')
    # This commented is not correct
    # return  render(request, 'index.html')

And to reference your static files in the templates (for example, index.html), do like this:

Image

So if you are under development, and using "python manage.py runserver" to test, all templates and static files should be successfully located by default. When I say by default, I mean these two default settings which tells django to look for templates and static files in each application:

STATICFILES_FINDERS = (
    'django.contrib.staticfiles.finders.FileSystemFinder',
    <span style="color: #ff0000;">'django.contrib.staticfiles.finders.AppDirectoriesFinder'</span>,
#   'django.contrib.staticfiles.finders.DefaultStorageFinder',
)

TEMPLATE_LOADERS = (
    'django.template.loaders.filesystem.Loader',
    <span style="color: #ff0000;">'django.template.loaders.app_directories.Loader'</span>,
#   'django.template.loaders.eggs.Loader',
)

But what you should do to serve the static files with apache? Normally static files are served by apache with following command

Alias /static/ PATH_TO_STATIC_FOLDER

So django provides another way, called collectstatic, which literally means collect all the static files from each application and put them under one folder. Open settings.py under MYPROJECT folder, and define the following variable:

# Put the absolute path of the folder where you want the collected files go. In this example, I put it beside the manage.py
STATIC_ROOT = 'PATH_TO_MYPROJECT/static/'

Also make sure that 'django.contrib.staticfiles' is listed under INSTALLED_APP.

Then use manage.py to do the collection work:

python manage.py collectstatic

Then a collected folder /static/ will appear under the project main folder:

├── APPLE
│   ├── css
│   ├── images
│   ├── js
│   ├── static
│   │   └── APPLE
│   │       ├── css
│   │       ├── images
│   │       └── js
│   └── templates
│       └── APPLE
├── BANANA
│   ├── css
│   ├── images
│   ├── js
│   ├── static
│   │   └── BANANA
│   │       ├── css
│   │       ├── images
│   │       └── js
│   └── templates
│       └── BANANA
├── MYPROJECT
└── static
    ├── APPLE
    │   ├── css
    │   ├── images
    │   └── js
    └── BANANA
        ├── css
        ├── images
        └── js

By doing this, you only need to define one Alias for static files in Apache configuration!

点击查看评论