django1/docs/overview.txt

309 lines
12 KiB
Plaintext
Raw Normal View History

==================
Django at a glance
==================
Because Django was developed in a fast-paced newsroom environment, it was
designed to make common Web-development tasks fast and easy. Here's an informal
overview of how to write a database-driven Web app with Django.
The goal of this document is to give you enough technical specifics to
understand how Django works, but this isn't intended to be a tutorial or
reference. Please see our more-detailed Django documentation_ when you're ready
to start a project.
.. _documentation: http://www.djangoproject.com/documentation/
Design your model
=================
Start by describing your database layout in Python code. Django's data-model API
offers many rich ways of representing your models -- so far, it's been
solving two years' worth of database-schema problems. Here's a quick example::
class Reporter(meta.Model):
fields = (
meta.CharField('full_name', "reporter's full name", maxlength=70),
)
def __repr__(self):
return self.full_name
class Article(meta.Model):
fields = (
meta.DateTimeField('pub_date', 'publication date'),
meta.CharField('headline', 'headline', maxlength=200),
meta.TextField('article', 'article'),
meta.ForeignKey(Reporter),
)
def __repr__(self):
return self.headline
Install it
==========
Next, run the Django command-line utility. It'll create the database tables for
you automatically, in the database specified in your Django settings. Django
works with PostgreSQL and MySQL, although other database adapters are on the
way::
django-admin.py install news
Enjoy the free API
==================
With that, you've got a free, and rich, Python API to access your data. The API
is created on the fly: No code generation necessary::
# Modules are dynamically created within django.models.
# Their names are plural versions of the model class names.
>>> from django.models.news import reporters, articles
# No reporters are in the system yet.
>>> reporters.get_list()
[]
# Create a new Reporter.
>>> r = reporters.Reporter(id=None, full_name='John Smith')
# Save the object into the database. You have to call save() explicitly.
>>> r.save()
# Now it has an ID.
>>> r.id
1
# Now the new reporter is in the database.
>>> reporters.get_list()
[John Smith]
# Fields are represented as attributes on the Python object.
>>> r.full_name
'John Smith'
# Django provides a rich database lookup API that's entirely driven by keyword arguments.
>>> reporters.get_object(id__exact=1)
John Smith
>>> reporters.get_object(full_name__startswith='John')
John Smith
>>> reporters.get_object(full_name__contains='mith')
John Smith
>>> reporters.get_object(id__exact=2)
Traceback (most recent call last):
...
django.models.polls.ReporterDoesNotExist: Reporter does not exist for {'id__exact': 2}
# Create an article.
>>> from datetime import datetime
>>> a = articles.Article(id=None, pub_date=datetime.now(), headline='Django is cool', article='Yeah.', reporter_id=1)
>>> a.save()
# Now the article is in the database.
>>> articles.get_list()
[Django is cool]
# Article objects get API access to related Reporter objects.
>>> r = a.get_reporter()
>>> r.full_name
'John Smith'
# And vice versa: Reporter objects get API access to Article objects.
>>> r.get_article_list()
[Django is cool]
# The API follows relationships as far as you need.
# Find all articles by a reporter whose name starts with "John".
>>> articles.get_list(reporter__full_name__startswith="John")
[Django is cool]
# Change an object by altering its attributes and calling save().
>>> r.full_name = 'Billy Goat'
>>> r.save()
# Delete an object with delete().
>>> r.delete()
A dynamic admin interface: It's not just scaffolding -- it's the whole house
============================================================================
Once your models are defined, Django can automatically create an administrative
interface -- a Web site that lets authenticated users add, change and
delete objects. It's as easy as adding an extra admin attribute to your model
classes::
class Article(meta.Model):
fields = (
meta.DateTimeField('pub_date', 'publication date'),
meta.CharField('headline', 'headline', maxlength=200),
meta.TextField('article', 'article'),
meta.ForeignKey(Reporter),
)
admin = meta.Admin(
fields = (
(None, {'fields': ('headline', 'article')}),
('Extra stuff', {'fields': ('pub_date', 'reporter_id')}),
),
)
The ``admin.fields`` defines the layout of your admin form. Each element in the
fields tuple corresponds to a ``<fieldset>`` in the form.
The philosophy here is that your site is edited by a staff, or a client, or
maybe just you -- and you don't want to have to deal with creating backend
interfaces just to manage content.
Our typical workflow at World Online is to create models and get the admin sites
up and running as fast as possible, so our staff journalists can start
populating data. Then we develop the way data is presented to the public.
Design your URLs
================
A clean, elegant URL scheme is an important detail in a high-quality Web
application. Django lets you design URLs however you want, with no framework
limitations.
To design URLs for an app, you create a Python module. For the above
Reporter/Article example, here's what that might look like::
from django.conf.urls.defaults import *
urlpatterns = patterns('',
(r'^/articles/(?P\d{4})/$', 'myproject.news.views.articles.year_archive'),
(r'^/articles/(?P\d{4})/(?P\d{2})/$', 'myproject.news.views.articles.month_archive'),
(r'^/articles/(?P\d{4})/(?P\d{2})/$', 'myproject.news.views.articles.month_archive'),
(r'^/articles/(?P\d{4})/(?P\d{2})/(?P\d+)/$', 'myproject.news.views.articles.article_detail'),
)
The code above maps URLs, as regular expressions, to the location of Python
callback functions (views). The regular expressions use parenthesis to "capture"
values from the URLs. When a user requests a page, Django runs through each
regular expression, in order, and stops at the first one that matches the
requested URL. (If none of them matches, Django calls a special 404 view.) This
is blazingly fast, because the regular expressions are compiled at load time.
Once one of the regexes matches, Django imports and calls the given view, which
is a simple Python function. Each view gets passed a request object --
which contains request metadata and lets you access GET and POST data as simple
dictionaries -- and the values captured in the regex, via keyword
arguments.
For example, if a user requested the URL "/articles/2005/05/39323/", Django
would call the function ``myproject.news.views.articles.article_detail(request,
year='2005', month='05', article_id='39323')``.
Write your views
================
Each view is responsible for doing one of two things: Returning an
``HttpResponse`` object containing the content for the requested page, or
raising an exception such as ``Http404``. The rest is up to you.
Generally, a view retrieves data according to the parameters, loads a template
and renders the template with the retrieved data. Here's an example view for
article_detail from above::
from django.models.news import articles
def article_detail(request, year, month, article_id):
# Use the Django API to find an object matching the URL criteria.
try:
a = articles.get_object(pub_date__year=year, pub_date__month=month, id__exact=article_id)
except articles.ArticleDoesNotExist:
raise Http404
t = template_loader.get_template('news/article_detail')
c = Context(request, {
'article': a,
})
content = t.render(c)
return HttpResponse(content)
This example uses Django's template system, which has several key features.
Design your templates
=====================
The code above loads the ``news/article_detail`` template.
Django has a template search path, which allows you to minimize redundancy among
templates. In your Django settings, you specify a list of directories to check
for templates. If a template doesn't exist in the first directory, it checks the
second, and so on.
Let's say the ``news/article_detail`` template was found. Here's what that might
look like::
{% extends "base" %}
{% block title %}{{ article.headline }}{% endblock %}
{% block content %}
<h1>{{ article.headline }}</h1>
<p>By {{ article.get_reporter.full_name }}</p>
<p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{{ article.article }}
{% endblock %}
It should look straightforward. Variables are surrounded by double-curly braces.
``{{ article.headline }}`` means "Output the value of the article's headline
attribute." But dots aren't used only for attribute lookup: They also can do
dictionary-key lookup, index lookup and function calls (as is the case with
``article.get_reporter``).
Note ``{{ article.pub_date|date:"F j, Y" }}`` uses a Unix-style "pipe" (the "|"
character). This is called a template filter, and it's a way to filter the value
of a variable. In this case, the date filter formats a Python datetime object in
the given format (as found in PHP's date function; yes, there is one good idea
in PHP).
You can chain together as many filters as you'd like. You can write custom
filters. You can write custom template tags, which run custom Python code behind
the scenes.
Finally, Django uses the concept of template inheritance: That's what the ``{%
extends "base" %}`` does. It means "First load the template called 'base', which
has defined a bunch of blocks, and fill the blocks with the following blocks."
In short, that lets you dramatically cut down on redundancy in templates: Each
template has to define only what's unique to that template.
Here's what the "base" template might look like::
<html>
<head>
<title>{% block title %}</title>
</head>
<body>
<img src="sitelogo.gif" alt="Logo" />
{% block content %}{% endblock %}
</body>
</html>
Simplistically, it defines the look-and-feel of the site (with the site's logo),
and provides "holes" for child templates to fill. This makes a site redesign as
easy as changing a single file -- the base template.
Note that you don't have to use Django's template system if you prefer another
system. While Django's template system is particularly well-integrated with
Django's model layer, nothing forces you to use it. For that matter, you don't
have to use Django's API, either. You can use another database abstraction
layer, you can read XML files, you can read files off disk, or anything you
want. Each piece of Django -- models, views, templates -- is decoupled
from the next.
This is just the surface
========================
This has been only a quick overview of Django's functionality. Some more useful
features:
* A caching framework that integrates with memcached or other backends.
* An RSS framework that makes creating RSS feeds as easy as writing a
small Python class.
* More sexy automatically-generated admin features -- this overview barely
scratched the surface
The next obvious steps are for you to download Django, read the documentation
and join the community. Thanks for your interest!