Django Projects¶
At its core, a Django project requires nothing more than a settings file. In practice, almost every project consists of the following items:
Settings¶
The settings module is the only true requirement for a Django project. Typically, it lives in the root of your project as settings.py
.
Handling Settings for Multiple Environments¶
Django’s startproject
command gives you a single settings.py
file. If you’re new to Django, stick with the single file while you learn the ropes. As you start to deploy production sites and work with more than one developer, you’ll realize the benefit in maintaining multiple settings files. For example, you probably want to run with DEBUG
on locally, but not in production.
There are numerous ways to handle multiple settings. Whatever solution you choose, it should meet the following requirements:
- All the important settings files are version controlled. If the settings change on your production site, you’ll want to know who made the changes and when they were made.
- All settings inherit from a common base. If you want to add
django-debug-toolbar
to yourINSTALLED_APPS
, you should be able to do it without redefining all yourINSTALLED_APPS
.
If you don’t want to think about it, simply use our Django project template when starting new projects. It is ready to support multiple projects out of the gate:
django-admin.py startproject --template=https://github.com/lincolnloop/django-layout/tarball/master -e py,rst,example,gitignore my_project_name
See also
- Django’s Split Settings Wiki
- Examples of handling multiple settings
Handling File Paths¶
One function of your settings is to tell Django where to find things such as your static media and templates. Most likely they’ll already live inside your project. If so, let Python generate the absolute path names for you. This makes your project portable across different environments.
import os
DIRNAME = os.path.dirname(__file__)
# ...
STATIC_ROOT = os.path.join(DIRNAME, 'static')
URLconf¶
By default, you’ll find your URLconf in the root of your project as urls.py
. It defines how requests should be routed for your project.
Keep it Simple¶
Your project URLconf should simply include URLconfs from your applications whenever possible. This keeps your application logic inside your application and your project simply serves as a pointer to it.
See also
- Django URL dispatcher documentation
- Including other URLconfs
Handling URLconfs for Multiple Environments¶
Just like your settings module, eventually, you’ll come across the need to run different URLconfs for different environments. You may want to use admin
locally, but not once deployed. Django already provides an easy way for you to do this with the ROOT_URLCONF setting.
This is basically the same scenario as having multiple settings. You can use the same solution here:
myproject
...
settings/
__init__.py
base.py <-- shared by all environments
def.py
production.py
urls/
__init__.py
base.py <-- shared by all environments
dev.py
production.py
...
See also
WSGI File¶
The WSGI file tells your WSGI server what it needs to do to serve your project on the web. Django’s default wsgi.py
is sufficient for most applications.
Local Applications¶
Local applications are Django applications that are domain-specific to your project. They typically live inside the project module and are so closely tied to your project, they would have little use outside of it.
Local vs. Third Party¶
There are hundreds [1] of open source Django applications available. Before you reinvent the wheel, make sure somebody hasn’t already solved your problem by searching on Google or Django Packages. If you find something that will work do not put it your project code, instead add it to your pip requirements.
[1] | http://djangopackages.com/categories/apps/ |
The Namespace¶
How local applications should be imported into your project is a source of ongoing debate in the Django community [2]. Fortunately, with the release of Django 1.4, the default manage.py
no longer changes the PYTHONPATH
[3], making this much less of an issue.
At Lincoln Loop, we put project applications inside the project namespace. This prevents polluting the global namespace and running into potential naming conflicts.
[2] | Discussion on django-developers mailing list regarding project namespaces in the tutorial |
[3] | Django 1.4 manage.py changes |
Templates¶
Location¶
Templates typically live in one of two places, inside the application or at the root level of a project. We recommend keeping all your templates in the project template directory unless you plan on including your application in multiple projects (or developing it as a open source “reusable” application). In that case, it can be helpful to ship with a set of sample templates in the application, allowing it to work out-of-the-box or serving as an example for other developers.
Naming¶
Django’s generic views provide an excellent pattern for naming templates. Following design patterns already found in Django can be helpful for a couple reasons.
- They have been well thought out and tested.
- It makes your code immediately understandable to new developers picking up your Django code.
Most generic view templates are named in the format:
[application]/[model]_[function].html
For example, creating a template to list all of the contacts (Contact
model) in my address book (address_book
application), I would use the following template:
address_book/contact_list.html
Similarly, a detail view of a contact would use:
address_book/contact_detail.html
Not every template you create will map so closely to a single model, however. In those cases, you’re on your own for naming, but should still keep your templates in a directory with the same name as your application.
When using inclusion tags or other other functionality to render partial templates, keep them in an includes
directory inside the application template directory. For example, if I had an inclusion tag to render a contact form inside my address book application, I would create a template for it at:
address_book/includes/contact_form.html
There is no rule (anymore) that templates must have an html
file extension. If you are rendering something else (plain text, JSON, XML, etc), your templates file extension should match that of the content you are generating.
Static Media¶
Static media encompasses all the non-dynamic content needed for your website: CSS, images, JavaScript, Flash, etc. It comes in two flavors, user-generated content and the media needed to render your site. Best practice dictates that your static media lives inside your project and your version control system. Certainly, we don’t want stuff our users’ uploads to go to the same place. As such, we always use django.contrib.staticfiles
[4].
In addition to some other slick features, staticfiles
gives you a static
template tag [5] that will properly locate your static files whether they are on your local computer or in a non-local storage on your production system. This leaves MEDIA_URL
and MEDIA_ROOT
to manage user generated content.
See also
[4] | https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/ |
[5] | https://docs.djangoproject.com/en/dev/ref/contrib/staticfiles/#std:templatetag-staticfiles-static |