Imported fledgeling Django documentation from private SVN repository
git-svn-id: http://code.djangoproject.com/svn/django/trunk@2 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
d6ded0e91b
commit
07ffc7d605
|
@ -0,0 +1,48 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
"""
|
||||||
|
Script to build the documentation for Django from ReST -> HTML.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import glob
|
||||||
|
import locale
|
||||||
|
from docutils.core import publish_parts
|
||||||
|
from docutils.writers import html4css1
|
||||||
|
|
||||||
|
SETTINGS = {
|
||||||
|
'initial_header_level': 2
|
||||||
|
}
|
||||||
|
|
||||||
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
|
|
||||||
|
def build(dirs):
|
||||||
|
writer = html4css1.Writer()
|
||||||
|
writer.translator_class = DjangoHTMLTranslator
|
||||||
|
for dir in dirs:
|
||||||
|
for fname in glob.glob1(dir, "*.txt"):
|
||||||
|
in_file = os.path.join(dir, fname)
|
||||||
|
out_file = os.path.join(dir, os.path.splitext(fname)[0] + ".html")
|
||||||
|
print "+++", in_file
|
||||||
|
parts = publish_parts(
|
||||||
|
open(in_file).read(),
|
||||||
|
source_path=in_file,
|
||||||
|
destination_path=out_file,
|
||||||
|
writer=writer,
|
||||||
|
settings_overrides={
|
||||||
|
'initial_header_level' : 2,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
open(out_file, 'w').write(parts['html_body'])
|
||||||
|
|
||||||
|
class DjangoHTMLTranslator(html4css1.HTMLTranslator):
|
||||||
|
"""Remove the damn border=1 from the standard HTML writer"""
|
||||||
|
def visit_table(self, node):
|
||||||
|
self.body.append(self.starttag(node, 'table', CLASS='docutils'))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
build(sys.argv[1:])
|
||||||
|
else:
|
||||||
|
build([os.getcwd()])
|
|
@ -0,0 +1,258 @@
|
||||||
|
======================
|
||||||
|
Database API reference
|
||||||
|
======================
|
||||||
|
|
||||||
|
XXX INTRO HERE XXX
|
||||||
|
|
||||||
|
Throughout this reference, I'll be referring to the following Poll application::
|
||||||
|
|
||||||
|
class Poll(meta.Model):
|
||||||
|
module_name = 'polls'
|
||||||
|
verbose_name = 'poll'
|
||||||
|
db_table = 'polls'
|
||||||
|
fields = (
|
||||||
|
meta.SlugField('slug', 'slug', unique_for_month='pub_date'),
|
||||||
|
meta.CharField('question', 'question', maxlength=255),
|
||||||
|
meta.DateTimeField('pub_date', 'date published'),
|
||||||
|
meta.DateTimeField('expire_date', 'expiration date'),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Choice(meta.Model):
|
||||||
|
module_name = 'choices'
|
||||||
|
verbose_name = 'choice'
|
||||||
|
db_table = 'poll_choices'
|
||||||
|
fields = (
|
||||||
|
meta.IntegerField('poll_id', 'poll', rel=meta.ManyToOne(Poll, 'poll', 'id',
|
||||||
|
edit_inline=True, edit_inline_type=meta.TABULAR, num_in_admin=10,
|
||||||
|
min_num_in_admin=5)),
|
||||||
|
meta.CharField('choice', 'choice', maxlength=255, core=True),
|
||||||
|
meta.IntegerField('votes', 'votes', editable=False, default=0),
|
||||||
|
)
|
||||||
|
|
||||||
|
Basic lookup functions
|
||||||
|
======================
|
||||||
|
|
||||||
|
Each model exposes three basic functions for lookups: ``get_object``,
|
||||||
|
``get_list``, and ``get_count``. These functions all take the same arguments,
|
||||||
|
but ``get_object`` assumes that only a single record will be returned (and
|
||||||
|
raises an exception if that's not true), ``get_count`` simple returns a count of
|
||||||
|
objects matched by the lookup, and ``get_list`` returns the entire list.
|
||||||
|
|
||||||
|
Field lookups
|
||||||
|
=============
|
||||||
|
|
||||||
|
Basic field lookups take the form ``field__lookuptype`` (that's a
|
||||||
|
double-underscore). For example::
|
||||||
|
|
||||||
|
polls.get_list(pub_date__lte=datetime.datetime.now())
|
||||||
|
|
||||||
|
translates (roughly) into the following SQL:
|
||||||
|
|
||||||
|
SELECT * FROM polls WHERE pub_date < NOW();
|
||||||
|
|
||||||
|
The DB API supports the following lookup types:
|
||||||
|
|
||||||
|
========== ==============================================================
|
||||||
|
Type Description
|
||||||
|
========== ==============================================================
|
||||||
|
exact Exact match: ``polls.get_object(id__exact=14)``
|
||||||
|
iexact Case-insensitive exact match:
|
||||||
|
``polls.get_list(slug__iexact="foo")`` matches a slug of ``foo``,
|
||||||
|
``FOO``, ``fOo``, etc.
|
||||||
|
contains Case-sensitive contains test:
|
||||||
|
``polls.get_list(question__contains="spam")`` returns all polls
|
||||||
|
that contain "spam" in the question.
|
||||||
|
icontains Case-insensitive contains
|
||||||
|
gt Greater than: ``polls.get_list(id__gt=4)``
|
||||||
|
gte Greater than or equal to
|
||||||
|
lt Less than
|
||||||
|
lte Less than or equal to
|
||||||
|
startswith Case-sensitive starts-with:
|
||||||
|
``polls.get_list(question_startswith="Would")``
|
||||||
|
endswith Case-sensitive ends-with
|
||||||
|
range Range test:
|
||||||
|
``polls.get_list(pub_date__range=(start_date, end_date)``
|
||||||
|
returns all polls with a pub_date between ``start_date``
|
||||||
|
and ``end_date`` (inclusive).
|
||||||
|
year For date/datetime fields, exact year match:
|
||||||
|
``polls.get_count(pub_date__year=2005)``.
|
||||||
|
month For date/datetime fields, exact month match.
|
||||||
|
day For date/datetime fields, exact day match.
|
||||||
|
isnull True/False; does is IF NULL/IF NOT NULL lookup:
|
||||||
|
``polls.get_list(expire_date__isnull=True)``.
|
||||||
|
========== ==============================================================
|
||||||
|
|
||||||
|
Multiple lookups are of course allowed, and are translated as "ands"::
|
||||||
|
|
||||||
|
polls.get_list(
|
||||||
|
pub_date__year=2005,
|
||||||
|
pub_date__month=1,
|
||||||
|
question__startswith="Would",
|
||||||
|
)
|
||||||
|
|
||||||
|
retrieves all polls published in Jan. 2005 whose question starts with "Would."
|
||||||
|
|
||||||
|
"Or" lookups are also possible::
|
||||||
|
|
||||||
|
XXX FIXME XXX
|
||||||
|
|
||||||
|
Ordering
|
||||||
|
========
|
||||||
|
|
||||||
|
The results are automatically ordered by the ordering tuple given by the
|
||||||
|
``ordering`` key in the model, but the ordering may be explicitly
|
||||||
|
provided by the ``order_by`` argument to a lookup::
|
||||||
|
|
||||||
|
polls.get_list(
|
||||||
|
pub_date__year=2005,
|
||||||
|
pub_date__month=1,
|
||||||
|
order_by=(("pub_date", "DESC"), ("question", "ASC")),
|
||||||
|
)
|
||||||
|
|
||||||
|
The result set above will be ordered by ``pub_date`` (descending), then
|
||||||
|
by ``question`` (ascending). Just like in models, the ``order_by`` clause
|
||||||
|
is a list of ordering tuples where the first element is the field and the
|
||||||
|
second is "ASC" or "DESC" to order ascending or descending. You may also
|
||||||
|
use the tuple ``(None, "RANDOM")`` to order the result set randomly.
|
||||||
|
|
||||||
|
Relationships (joins)
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Joins may implicitly be performed by following relationships:
|
||||||
|
``choices.get_list(poll__slug__exact="eggs")`` fetches a list of ``Choice``
|
||||||
|
objects where the associated ``Poll`` has a slug of ``eggs``. Multiple levels
|
||||||
|
of joins are allowed.
|
||||||
|
|
||||||
|
Given an instance of an object, related objects can be looked up directly using
|
||||||
|
connivence functions, for example, if ``poll`` is a ``Poll`` instance,
|
||||||
|
``poll.get_choice_list()`` will return a list of all associated choices (astute
|
||||||
|
readers will note that this is the same as
|
||||||
|
``choices.get_list(poll_id__exact=poll.id)``, except clearer).
|
||||||
|
|
||||||
|
Each type of relationship creates a set of methods on each object in the
|
||||||
|
relationship. These created methods go both ways, so objects that are
|
||||||
|
"related-to" need not explicitly define reverse relationships; that happens
|
||||||
|
automatically.
|
||||||
|
|
||||||
|
One-to-one relations
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
Each object in a one-to-one relationship will have a ``get_relatedobject()``
|
||||||
|
method. For example::
|
||||||
|
|
||||||
|
class Place(meta.Model):
|
||||||
|
...
|
||||||
|
fields = (
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
class Restaurant(meta.Model):
|
||||||
|
...
|
||||||
|
fields = (
|
||||||
|
meta.IntegerField('id', 'ID', primary_key=True,
|
||||||
|
rel=meta.OneToOne(places.Place, 'place', 'id')),
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
In the above example, each ``Place`` will have a ``get_restaurant()`` method,
|
||||||
|
and each ``Restaurant`` will have a ``get_place()`` method.
|
||||||
|
|
||||||
|
Many-to-one relations
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
In each many-to-one relationship the related object will have a
|
||||||
|
``get_relatedobject()`` method, and the related-to object will have
|
||||||
|
``get_relatedobject()``, ``get_relatedobject_list()``, and
|
||||||
|
``get_relatedobject_count()`` methods (the same as the module-level
|
||||||
|
``get_object()``, ``get_list()``, and ``get_count()`` methods).
|
||||||
|
|
||||||
|
Thus, for the ``Poll`` example at the top, ``Choice`` objects will have a
|
||||||
|
``get_poll()`` method, and ``Poll`` objects will have ``get_choice()``,
|
||||||
|
``get_choice_list()``, and ``get_choice_count()`` functions.
|
||||||
|
|
||||||
|
Many-to-many relations
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Many-to-many relations result in the same set of methods as `Many-to-one relations`_,
|
||||||
|
except that the ``get_relatedobjects()`` function on the related object will
|
||||||
|
return a list of instances instead of a single instance. So, if the relationship
|
||||||
|
between ``Poll`` and ``Choice`` was many-to-many, ``choice.get_polls()`` would
|
||||||
|
return a list.
|
||||||
|
|
||||||
|
Relationships across applications
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
If a relation spans applications -- if ``Place`` was had a ManyToOne relation to
|
||||||
|
a ``geo.City`` object, for example -- the name of the other application will be
|
||||||
|
added to the method, i.e. ``place.get_geo_city()`` and
|
||||||
|
``city.get_places_place_list()``.
|
||||||
|
|
||||||
|
Selecting related objects
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Relations are the bread and butter of databases, so there's an option to "follow"
|
||||||
|
all relationships and pre-fill them in a simple cache so that later calls to
|
||||||
|
objects with a one-to-many relationship don't have to hit the database. If you pass
|
||||||
|
``select_related=True`` to a lookup, this pre-caching of relationships will be performed.
|
||||||
|
This results in (sometimes much) larger queries, but it means that later use of
|
||||||
|
relationships is much faster.
|
||||||
|
|
||||||
|
For example, using the Poll and Choice models from above, if you do the following::
|
||||||
|
|
||||||
|
c = choices.get_object(id__exact=5, select_related=True)
|
||||||
|
|
||||||
|
Then subsequent calls to ``c.get_poll()`` won't hit the database.
|
||||||
|
|
||||||
|
Limiting selected rows
|
||||||
|
======================
|
||||||
|
|
||||||
|
The ``limit``, ``offset``, and ``distinct`` keywords can be used to control
|
||||||
|
which rows are returned. Both ``limit`` and ``offset`` should be integers which
|
||||||
|
will be directly passed to the SQL ``LIMIT``/``OFFSET`` commands.
|
||||||
|
|
||||||
|
If ``distinct`` is True, only distinct rows will be returned (this is equivalent
|
||||||
|
to a ``SELECT DISTINCT`` SQL clause).
|
||||||
|
|
||||||
|
Other lookup options
|
||||||
|
====================
|
||||||
|
|
||||||
|
There are a few other ways of more directly controlling the generated SQL
|
||||||
|
for the lookup. Note that by definition these extra lookups may not be
|
||||||
|
portable to different database engines (since you're explicitly writing
|
||||||
|
SQL code) and should be avoided where ever possible.:
|
||||||
|
|
||||||
|
``params``
|
||||||
|
----------
|
||||||
|
|
||||||
|
All the extra-SQL params described below may use standard Python string
|
||||||
|
formatting codes to indicate parameters that the database engine will
|
||||||
|
automatically quote. The ``params`` argument can contain any extra
|
||||||
|
parameters to be substituted.
|
||||||
|
|
||||||
|
``select``
|
||||||
|
----------
|
||||||
|
|
||||||
|
The ``select`` keyword allows you to select extra fields. This should be a
|
||||||
|
dict mapping field names to a SQL clause to use for that field. For example::
|
||||||
|
|
||||||
|
polls.get_list(
|
||||||
|
select={
|
||||||
|
'choice_count' : 'SELECT COUNT(*) FROM choices WHERE poll_id = polls.id'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
Each of the resulting ``Poll`` objects will have an extra ``choice_count`` with
|
||||||
|
a count of associated ``Choice`` objects. Note that the parenthesis required by
|
||||||
|
most database engines around sub-selects are not required in Django's ``select``
|
||||||
|
clauses.
|
||||||
|
|
||||||
|
``where`` / ``tables``
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
If you need to explicitly pass extra ``WHERE`` clauses -- perhaps to perform
|
||||||
|
non-explicit joins -- use the ``where`` keyword.. If you need to
|
||||||
|
join other tables into your query, you can pass their names to ``tables``.
|
||||||
|
|
||||||
|
Creating new objects
|
||||||
|
====================
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
Binary file not shown.
After Width: | Height: | Size: 58 KiB |
|
@ -0,0 +1,760 @@
|
||||||
|
===============
|
||||||
|
Model reference
|
||||||
|
===============
|
||||||
|
|
||||||
|
XXX INTRO XXX
|
||||||
|
|
||||||
|
Options for models
|
||||||
|
==================
|
||||||
|
|
||||||
|
A list of all possible options for a model object follows. Although there's a wide
|
||||||
|
array of possible options, only ``fields`` is required.
|
||||||
|
|
||||||
|
``admin``
|
||||||
|
---------
|
||||||
|
|
||||||
|
A ``meta.Admin`` object; see `Admin options`_. If this field isn't given,
|
||||||
|
the object will not have an admin interface.
|
||||||
|
|
||||||
|
``db_table``
|
||||||
|
------------
|
||||||
|
|
||||||
|
The name of the database table to use for the module::
|
||||||
|
|
||||||
|
db_table = "pizza_orders"
|
||||||
|
|
||||||
|
If not given, this will use ``app_label + '_' + module_name``.
|
||||||
|
|
||||||
|
``exceptions``
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Names of extra exception subclasses to include in the generated module.
|
||||||
|
These exceptions are available from instance methods and from module-level
|
||||||
|
methods::
|
||||||
|
|
||||||
|
exceptions = ("DisgustingToppingsException", "BurntCrust")
|
||||||
|
|
||||||
|
``fields``
|
||||||
|
----------
|
||||||
|
|
||||||
|
A list of field objects; see `Field objects`_. For example::
|
||||||
|
|
||||||
|
fields = (
|
||||||
|
meta.CharField('customer_name', 'customer name', maxlength=15),
|
||||||
|
meta.BooleanField('use_extra_cheese', 'use extra cheese'),
|
||||||
|
meta.IntegerField('customer_type', 'customer type', choices=CUSTOMER_TYPE_CHOICES),
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
|
``get_latest_by``
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
The name of a date or datetime field; if given, the module will have a
|
||||||
|
``get_latest()`` function which fetches the "latest" object in terms of
|
||||||
|
that field::
|
||||||
|
|
||||||
|
get_latest_by = "order_date"
|
||||||
|
|
||||||
|
``module_constants``
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
A dict of name/values to use as extra module-level constants::
|
||||||
|
|
||||||
|
module_constants = {
|
||||||
|
'MEAT_TYPE_PEPPERONI' : 1,
|
||||||
|
'MEAT_TYPE_SAUSAGE' : 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
``module_name``
|
||||||
|
---------------
|
||||||
|
|
||||||
|
The name of the module::
|
||||||
|
|
||||||
|
module_name = "pizza_orders"
|
||||||
|
|
||||||
|
If not given this will use a lowercased version of the class name.
|
||||||
|
|
||||||
|
``order_with_respect_to``
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
Marks this object as "orderable" with respect to the given field. This is
|
||||||
|
almost always used with related objects to allow them to be ordered with
|
||||||
|
respect to a parent object. For example, if a ``PizzaToppping`` relates to
|
||||||
|
a ``Pizza`` object, you might use::
|
||||||
|
|
||||||
|
order_with_respect_to = 'pizza_id'
|
||||||
|
|
||||||
|
to allow the toppings to be ordered with respect to the associated pizza.
|
||||||
|
|
||||||
|
``ordering``
|
||||||
|
------------
|
||||||
|
|
||||||
|
The default ordering for tho object::
|
||||||
|
|
||||||
|
ordering = (('order_date', 'DESC'),)
|
||||||
|
|
||||||
|
This is a tuple of 2-tuples; each 2-tuple is ``(field_name, ordering_type)``
|
||||||
|
where ordering_type is either ``"ASC"`` or ``"DESC"``. You may also use the
|
||||||
|
magic ``(None, "RANDOM")`` ordering tuple for random ordering.
|
||||||
|
|
||||||
|
``permissions``
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Extra permissions to enter into the permissions table when creating this
|
||||||
|
object. A add, delete, and change permission is automatically created for
|
||||||
|
each object; this option specifies extra permissions::
|
||||||
|
|
||||||
|
permissions = (("may_delivier_pizzas", "Can deliver pizzas"),)
|
||||||
|
|
||||||
|
This is a list of 2-tuples of
|
||||||
|
``(permission_code, human_readable_permission_name)``.
|
||||||
|
|
||||||
|
``unique_together``
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Sets of field names that, taken together, must be unique::
|
||||||
|
|
||||||
|
unique_together = (("driver_id", "restaurant_id"),)
|
||||||
|
|
||||||
|
This is a list of lists of fields that must be unique when considered
|
||||||
|
together.
|
||||||
|
|
||||||
|
``verbose_name``
|
||||||
|
----------------
|
||||||
|
|
||||||
|
A human-readable name for the object, singular::
|
||||||
|
|
||||||
|
verbose_name = "pizza"
|
||||||
|
|
||||||
|
If not given, this will use a munged version of the class name:
|
||||||
|
``CamelCase`` becomes ``camel case``.
|
||||||
|
|
||||||
|
``verbose_name_plural``
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The plural name for the object::
|
||||||
|
|
||||||
|
verbose_name_plural = "stories"
|
||||||
|
|
||||||
|
If not given, ``verbose_name + "s"`` will automatically be used.
|
||||||
|
|
||||||
|
Field objects
|
||||||
|
=============
|
||||||
|
|
||||||
|
The list of fields is the most important part of a data model. Each item in
|
||||||
|
the ``fields`` list is an instance of a ``meta.Field`` subclass, and maps to
|
||||||
|
a database field.
|
||||||
|
|
||||||
|
All field objects -- except for ``ForeignKey`` and ``ManyToManyField`` (see
|
||||||
|
below) -- take two positional arguments and a number of keyword arguments.
|
||||||
|
The positional arguments are the field name and the human-readable name. The
|
||||||
|
field name must be a valid Python identifier, but the human-readable name can
|
||||||
|
contain spaces, punctuation, etc.
|
||||||
|
|
||||||
|
General field options
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
Each type of field takes a different set of options, but there are some
|
||||||
|
options that are common to all field types. These options are:
|
||||||
|
|
||||||
|
====================== ===================================================
|
||||||
|
Option Description
|
||||||
|
====================== ===================================================
|
||||||
|
``blank`` If ``True``, the field is allowed to be blank.
|
||||||
|
Note that this is different from ``null`` in that
|
||||||
|
string fields will store the empty string instead of
|
||||||
|
``NULL`` internally; this means that to create a
|
||||||
|
field that stores nulls you must pass ``blank=True``
|
||||||
|
and ``null=True`` .
|
||||||
|
|
||||||
|
``choices`` A list of 2-tuples to use as choices for this
|
||||||
|
field.If this is given, instead of the standard
|
||||||
|
field a option menu will be used, limiting choices
|
||||||
|
to the choices given. A choices list looks like::
|
||||||
|
|
||||||
|
YEAR_IN_SCHOOL_CHOICES = (
|
||||||
|
('FR', 'Freshman'),
|
||||||
|
('SO', 'Sophomore'),
|
||||||
|
('JR', 'Junior'),
|
||||||
|
('SR', 'Senior'),
|
||||||
|
('GR', 'Graduate'),
|
||||||
|
)
|
||||||
|
|
||||||
|
The first element in each tuple is the actual value
|
||||||
|
to be stored; the second element is the human
|
||||||
|
readable name for the option.
|
||||||
|
|
||||||
|
``core`` For objects that are edited inline to a related
|
||||||
|
object (see Relationships_). If all "core" fields
|
||||||
|
in an inline-edited object are cleared, the
|
||||||
|
object will be considered to be deleted.
|
||||||
|
|
||||||
|
It is an error to have an inline-editable
|
||||||
|
relation without at least one core field.
|
||||||
|
|
||||||
|
``db_index`` If ``True``, the SQL generator will create a database
|
||||||
|
index on this field.
|
||||||
|
|
||||||
|
``default`` The default value for the field.
|
||||||
|
|
||||||
|
``editable`` ``True`` by default, if set to ``False`` the field
|
||||||
|
will not be editable in the admin.
|
||||||
|
|
||||||
|
``help_text`` Extra "help" text to be displayed with the field.
|
||||||
|
|
||||||
|
``null`` If ``True`` empty values in the field will be
|
||||||
|
stored as ``NULL`` in the database.
|
||||||
|
|
||||||
|
XXX does null imply blank? XXX
|
||||||
|
|
||||||
|
``primary_key`` If ``True`` this field is the primary key for the
|
||||||
|
table. You only need to use this if you don't want
|
||||||
|
the standard "id" field created and used as the
|
||||||
|
primary key.
|
||||||
|
|
||||||
|
Implies ``blank=False``, ``null=False``, and
|
||||||
|
``unique=True``. Only one primary key is allowed
|
||||||
|
on each object.
|
||||||
|
|
||||||
|
``radio_admin`` If ``choices`` is given, or if the field is a
|
||||||
|
ManyToOne relation, use a radio button interface
|
||||||
|
for the choices instead of the standard options
|
||||||
|
menu interface.
|
||||||
|
|
||||||
|
``rel`` The field's relation; see Relationships_.
|
||||||
|
|
||||||
|
``unique`` If ``True`` this field must be unique throughout
|
||||||
|
the table.
|
||||||
|
|
||||||
|
``unique_for_date`` Set this to the name of a ``DateField`` or
|
||||||
|
``DateTimeField`` to require that this field
|
||||||
|
be unique for the value of the date field. That
|
||||||
|
is, if you have a field, ``title`` that has
|
||||||
|
``unique_for_date="pub_date"``, then it is an
|
||||||
|
error to have two rows with the same ``title``
|
||||||
|
and the same ``pub_date``.
|
||||||
|
|
||||||
|
``unique_for_month`` Like ``unique_for_date``, but requires the field
|
||||||
|
to be unique with respect to the month.
|
||||||
|
|
||||||
|
``unique_for_year`` Like ``unique_for_date`` and ``unique_for_month``
|
||||||
|
but, well, you get the idea.
|
||||||
|
|
||||||
|
``validator_list`` A list of extra validators to apply to the field.
|
||||||
|
See the `Form fields guide`_ for information about
|
||||||
|
validators.
|
||||||
|
====================== ===================================================
|
||||||
|
|
||||||
|
.. _`Form fields guide`: http://www.djangoproject.com/FIXME/
|
||||||
|
|
||||||
|
Field Types
|
||||||
|
-----------
|
||||||
|
|
||||||
|
``AutoField``
|
||||||
|
`````````````
|
||||||
|
|
||||||
|
An ``IntegerField`` that automatically increments. You usually won't need to
|
||||||
|
use this directly; a primary key field will automatically be added to your
|
||||||
|
model if you don't specify otherwise. That automatically added field is::
|
||||||
|
|
||||||
|
meta.AutoField('id', 'ID', primary_key=True)
|
||||||
|
|
||||||
|
``BooleanField``
|
||||||
|
````````````````
|
||||||
|
|
||||||
|
A true/false field.
|
||||||
|
|
||||||
|
``CharField``
|
||||||
|
`````````````
|
||||||
|
|
||||||
|
A text field. These are displayed in the admin as single-line text inputs, so
|
||||||
|
for large amounts of text use a ``TextField``.
|
||||||
|
|
||||||
|
``CharField``s have an extra required argument: ``maxlength``; the maximum
|
||||||
|
length (in characters) of the field.
|
||||||
|
|
||||||
|
``CommaSeparatedIntegerField``
|
||||||
|
``````````````````````````````
|
||||||
|
|
||||||
|
A field of integers separated by commas.
|
||||||
|
|
||||||
|
``DateField``
|
||||||
|
`````````````
|
||||||
|
|
||||||
|
A, um, date field. Has a few extra optional options:
|
||||||
|
|
||||||
|
====================== ===================================================
|
||||||
|
Option Description
|
||||||
|
====================== ===================================================
|
||||||
|
``auto_now`` Automatically set the field to now every time the
|
||||||
|
object is saved. Useful for "last-modified"
|
||||||
|
timestamps.
|
||||||
|
|
||||||
|
``auto_now_add`` Automatically set the field to now when the object
|
||||||
|
is first created. Useful for creation timestamps.
|
||||||
|
====================== ===================================================
|
||||||
|
|
||||||
|
``DateTimeField``
|
||||||
|
`````````````````
|
||||||
|
|
||||||
|
A date and time field. Takes the same extra options as ``DateField``.
|
||||||
|
|
||||||
|
|
||||||
|
``EmailField``
|
||||||
|
``````````````
|
||||||
|
|
||||||
|
A ``CharField`` that checks that the value is a valid email address. Because
|
||||||
|
validating email addresses can be tricky, this is a pretty loose test.
|
||||||
|
|
||||||
|
``FileField``
|
||||||
|
`````````````
|
||||||
|
|
||||||
|
A file-upload field. Takes on additional option, ``upload_to`` which is
|
||||||
|
a path to upload the file to. This path may contain `strftime formatting`_
|
||||||
|
which will be replaced by the date/time of the file upload (so that uploaded
|
||||||
|
files don't fill up the given directory).
|
||||||
|
|
||||||
|
.. _`strftime formatting`: http://docs.python.org/lib/module-time.html#l2h-1941
|
||||||
|
|
||||||
|
``FloatField``
|
||||||
|
``````````````
|
||||||
|
|
||||||
|
A floating-point number. Has two additional required options:
|
||||||
|
|
||||||
|
====================== ===================================================
|
||||||
|
Option Description
|
||||||
|
====================== ===================================================
|
||||||
|
``max_digits`` The maximum number of digits allowed in the number.
|
||||||
|
|
||||||
|
``decimal_places`` The number of decimal places to store with the
|
||||||
|
number
|
||||||
|
====================== ===================================================
|
||||||
|
|
||||||
|
For example, to store numbers up to 999 with a resolution of 2 decimal places,
|
||||||
|
you'd use::
|
||||||
|
|
||||||
|
meta.FloatField(..., max_digits=5, decimal_places=2)
|
||||||
|
|
||||||
|
And to store numbers up to one million with a resolution of 10 decimal places::
|
||||||
|
|
||||||
|
meta.FloatField(..., max_digits=19, decimal_places=10)
|
||||||
|
|
||||||
|
``ForeignKey``
|
||||||
|
``````````````
|
||||||
|
|
||||||
|
A many-to-one relationship to the primary key in another object. So, to give a
|
||||||
|
``Topping`` object a many-to-one relationship to ``Pizza`` (i.e. there are
|
||||||
|
many toppings on a pizza)::
|
||||||
|
|
||||||
|
meta.ForeignKey(Pizza)
|
||||||
|
|
||||||
|
This is equivalent to (but much clearer than)::
|
||||||
|
|
||||||
|
meta.IntegerField('pizza_id', 'pizza', rel=meta.ManyToOne(Pizza, 'pizza', 'id'))
|
||||||
|
|
||||||
|
``ForeignKey`` fields take all the arguments of ``ManyToOne`` relations (see
|
||||||
|
Relationships_, below for what those arguments are), plus the following extra
|
||||||
|
options:
|
||||||
|
|
||||||
|
====================== ===================================================
|
||||||
|
Option Description
|
||||||
|
====================== ===================================================
|
||||||
|
``to_field`` The field on the related object that the relation
|
||||||
|
is to. This is almost always ``id``, but if the
|
||||||
|
PK on the other object is named something
|
||||||
|
different, this is how to indicate that.
|
||||||
|
|
||||||
|
``rel_name`` The name of the relation. In the above exmaple,
|
||||||
|
this would default to 'pizza' (so that the
|
||||||
|
``Toppings`` object would have a ``get_pizza()``
|
||||||
|
function; if you set ``rel_name`` to "pie", then
|
||||||
|
the function would be called ``get_pie()`` and the
|
||||||
|
field name would be ``pie_id``.
|
||||||
|
====================== ===================================================
|
||||||
|
|
||||||
|
|
||||||
|
``ImageField``
|
||||||
|
``````````````
|
||||||
|
|
||||||
|
Like a ``FieldField``, but validates that the uploaded object is a valid
|
||||||
|
image. Has two extra optional arguments, ``height_field`` and ``width_field``
|
||||||
|
which, if set, will be auto-populated with the height and width of the image.
|
||||||
|
|
||||||
|
``IntegerField``
|
||||||
|
````````````````
|
||||||
|
|
||||||
|
An integer, surprisingly.
|
||||||
|
|
||||||
|
``IPAddressField``
|
||||||
|
``````````````````
|
||||||
|
|
||||||
|
An IP address, in string format (i.e. "24.124.1.30").
|
||||||
|
|
||||||
|
``ManyToManyField``
|
||||||
|
```````````````````
|
||||||
|
|
||||||
|
XXX document once Adrian reworks this XXX
|
||||||
|
|
||||||
|
``NullBooleanField``
|
||||||
|
````````````````````
|
||||||
|
|
||||||
|
Like a ``BooleanField``, but allows ``NULL`` as one of the options. Use this
|
||||||
|
instead of a ``BooleanField`` with ``null=True`` .
|
||||||
|
|
||||||
|
``PhoneNumberField``
|
||||||
|
````````````````````
|
||||||
|
|
||||||
|
Validates that the value is a valid phone number.
|
||||||
|
|
||||||
|
``PositiveIntegerField``
|
||||||
|
````````````````````````
|
||||||
|
|
||||||
|
Like an ``IntegerField``, but must be positive.
|
||||||
|
|
||||||
|
``PositiveSmallIntegerField``
|
||||||
|
`````````````````````````````
|
||||||
|
|
||||||
|
Like a ``PositiveIntegerField``, but only allows values below 32767.
|
||||||
|
|
||||||
|
|
||||||
|
``SlugField``
|
||||||
|
`````````````
|
||||||
|
|
||||||
|
A "slug" suitable for parts of a URL; only allows alpha-numeric characters and
|
||||||
|
underscores.
|
||||||
|
|
||||||
|
Implies ``maxlength=50`` and ``db_index=True``.
|
||||||
|
|
||||||
|
Accepts an extra option, ``prepopulate_from`` which is a list of fields from
|
||||||
|
which to auto-populate the slug.
|
||||||
|
|
||||||
|
``SmallIntegerField``
|
||||||
|
`````````````````````
|
||||||
|
|
||||||
|
Like an ``IntegerField``, but must be between -32768 and 32767.
|
||||||
|
|
||||||
|
``TextField``
|
||||||
|
`````````````
|
||||||
|
|
||||||
|
A large text field (``<textarea>`` in HTML).
|
||||||
|
|
||||||
|
``TimeField``
|
||||||
|
`````````````
|
||||||
|
|
||||||
|
A time. Accepts the same auto-population options as ``DateField`` and
|
||||||
|
``DateTimeField``.
|
||||||
|
|
||||||
|
``URLField``
|
||||||
|
````````````
|
||||||
|
|
||||||
|
A field for a URL. If the ``verify_exists`` option is ``True``, the URL given
|
||||||
|
will be checked for existence (i.e. actually loads and doesn't give a 404
|
||||||
|
response).
|
||||||
|
|
||||||
|
``USStateField``
|
||||||
|
````````````````
|
||||||
|
|
||||||
|
A US state.
|
||||||
|
|
||||||
|
``XMLField``
|
||||||
|
````````````
|
||||||
|
|
||||||
|
A field containing XML. Takes one required argument, ``schema_path`` which
|
||||||
|
is the path to a RelaxNG_ scheme against which to validate the field.
|
||||||
|
|
||||||
|
.. _RelaxNG: http://www.relaxng.org/
|
||||||
|
|
||||||
|
Relationships
|
||||||
|
=============
|
||||||
|
|
||||||
|
The ``rel`` option for a field marks that field as being a relationship to
|
||||||
|
another object. For the most common cases, using ``ForeignKey`` or
|
||||||
|
``ManyToManyField`` is best; these "shortcuts" encapsulate best practices
|
||||||
|
in database design (i.e. using integer foreign keys into another table's
|
||||||
|
primary key). If you do need to explicitly create a relation, these relation
|
||||||
|
objects should be used as the value of the ``rel`` attribute. Also, all
|
||||||
|
the options for ``ManyToOne`` are allowed as options for ``ForeignKey``,
|
||||||
|
and the same goes for ``ManyToMany`` and ``ManyToManyField``.
|
||||||
|
|
||||||
|
``ManyToOne``
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Signifies a many-to-one relation: if a ``Pizza`` can have many ``Topping``s,
|
||||||
|
then the ``Topping`` object should have a ``ManyToOne`` relation to ``Pizza``.
|
||||||
|
|
||||||
|
The three positional arguments to ``ManyToMany`` are:
|
||||||
|
|
||||||
|
* The class to relate to (i.e. ``Pizza`` or ``core.Site``).
|
||||||
|
|
||||||
|
* The name of the relation (i.e. ``pizza``, or ``site``); this is used in
|
||||||
|
the generated functions for managing that relationship (i.e.
|
||||||
|
``get_pizza`` and ``get_site``).
|
||||||
|
|
||||||
|
* The name of the field the relationship "points" to. In most cases this
|
||||||
|
will be "id", but if the other object's PK isn't named "id", this
|
||||||
|
must match the PK field name.
|
||||||
|
|
||||||
|
The keyword arguments accepted by ``ManyToOne`` are:
|
||||||
|
|
||||||
|
======================= ==================================================
|
||||||
|
Option Description
|
||||||
|
======================= ==================================================
|
||||||
|
``edit_inline`` If ``True``, this related object is edited
|
||||||
|
"inline" on the related object's page. This means
|
||||||
|
that the object will not have its own admin
|
||||||
|
interface.
|
||||||
|
|
||||||
|
``edit_inline_type`` This is either ``meta.TABULAR`` or
|
||||||
|
``meta.STACKED`` and controls weather the inline
|
||||||
|
editable objects are displayed as a table or as
|
||||||
|
a "stack" of fieldsets. Defaults to
|
||||||
|
``meta.STACKED``.
|
||||||
|
|
||||||
|
``limit_choices_to`` A dictionary of lookup arguments and values (see
|
||||||
|
the `Dictionary API reference`_) to limit choices
|
||||||
|
of this object to. Use this along with
|
||||||
|
``meta.LazyDate`` to limit choices of objects
|
||||||
|
by date, for example::
|
||||||
|
|
||||||
|
limit_choices_to = {'pub_date__lte' : meta.LazyDate()}
|
||||||
|
|
||||||
|
only allows the choice of related objects with a
|
||||||
|
``pub_date`` before the current date/time to be
|
||||||
|
chosen.
|
||||||
|
|
||||||
|
Not compatible with ``edit_inline``.
|
||||||
|
|
||||||
|
``lookup_overrides`` XXX FIXME XXX
|
||||||
|
|
||||||
|
``max_num_in_admin`` For inline-edited objects, this is the maximum
|
||||||
|
number of related objects to display in the admin.
|
||||||
|
Thus, if a pizza could only have up to 10
|
||||||
|
toppings, ``max_num_in_admin=10`` would ensure
|
||||||
|
that a user never enters more than 10 toppings.
|
||||||
|
|
||||||
|
Note that this doesn't ensure more than 10 related
|
||||||
|
toppings ever get created.
|
||||||
|
|
||||||
|
``min_num_in_admin`` The minimum number of related objects displayed in
|
||||||
|
the admin. Normally, at the creation stage
|
||||||
|
``num_in_admin`` inline objects are shown, and at
|
||||||
|
the edit stage ``num_extra_on_change`` objects are
|
||||||
|
shown in addition to all pre-existing related
|
||||||
|
objects. However, no fewer than
|
||||||
|
``min_num_in_admin`` related objects will ever be
|
||||||
|
displayed.
|
||||||
|
|
||||||
|
``num_extra_on_change`` The number of extra blank related object fields to
|
||||||
|
show at the change stage.
|
||||||
|
|
||||||
|
``num_in_admin`` The default number of inline objects to display
|
||||||
|
on the object page at the add stage.
|
||||||
|
|
||||||
|
``raw_id_admin`` Only display a field for the integer to be entered
|
||||||
|
instead of a drop-down menu. This is useful when
|
||||||
|
related to an object type that will have too many
|
||||||
|
rows to make a menu practical.
|
||||||
|
|
||||||
|
Not used with ``edit_inline``.
|
||||||
|
|
||||||
|
``related_name`` The name to use for the relation from the related
|
||||||
|
object back to this one. For example, when if
|
||||||
|
``Topping`` has this field::
|
||||||
|
|
||||||
|
meta.ForeignKey(Pizza)
|
||||||
|
|
||||||
|
the ``related_name`` will be "topping" (taken from
|
||||||
|
the class name which will in turn give ``Pizza``
|
||||||
|
methods like ``get_topping_list()`` and
|
||||||
|
``get_topping_count()``.
|
||||||
|
|
||||||
|
If you instead were to use::
|
||||||
|
|
||||||
|
meta.ForeignKey(Pizza, related_name="munchie")
|
||||||
|
|
||||||
|
then the methods would be called
|
||||||
|
``get_munchie_list()``, ``get_munchie_count()``,
|
||||||
|
etc.
|
||||||
|
|
||||||
|
This is only really useful when you have a single
|
||||||
|
object that relates to the same object more than
|
||||||
|
once. For example, if a ``Story`` object has both
|
||||||
|
``primary_category`` and ``secondary_category``
|
||||||
|
fields, to make sure that the category objects
|
||||||
|
have the correct methods, you'd use fields like::
|
||||||
|
|
||||||
|
...
|
||||||
|
meta.ForeignKey(Category, name="primary_category_id",
|
||||||
|
rel_name="primary_category",
|
||||||
|
related_name="primary_story"),
|
||||||
|
|
||||||
|
meta.ForeignKey(Category, name="secondary_category_id",
|
||||||
|
rel_name="secondary_category",
|
||||||
|
related_name="secondary_story"),
|
||||||
|
...
|
||||||
|
|
||||||
|
which would give the category objects methods
|
||||||
|
named ``get_primary_story_list()`` and
|
||||||
|
``get_secondary_story_list()``.
|
||||||
|
======================= ==================================================
|
||||||
|
|
||||||
|
.. _`Dictionary API reference`: http://www.djangoproject.com/FIXME/
|
||||||
|
|
||||||
|
``ManyToMany``
|
||||||
|
--------------
|
||||||
|
|
||||||
|
XXX will this still exist given the changes to ManyToManyField? XXX
|
||||||
|
|
||||||
|
``OneToOne``
|
||||||
|
------------
|
||||||
|
|
||||||
|
Signifies a one-to-one relationship. This is most useful on the primary key
|
||||||
|
of an object when that object "extends" another object in some way.
|
||||||
|
|
||||||
|
For example, if you are building a database of "places", you would build pretty
|
||||||
|
standard stuff like address, phone number, etc. in the database. If you then
|
||||||
|
wanted to build a database of restaurants on top of the places, instead of
|
||||||
|
repeating yourself and replicating those fields in the restaurants object, you
|
||||||
|
could make ``Restaurant`` have a ``OneToOne`` relation to ``Place`` (since
|
||||||
|
a restaurant "is-a" place).
|
||||||
|
|
||||||
|
This has a few repercussions in the admin interface:
|
||||||
|
|
||||||
|
* No selection interface is displayed on ``Restaurant`` pages; there will
|
||||||
|
be one (and only one) ``Restaurant`` for each place.
|
||||||
|
|
||||||
|
* On the ``Restaurant`` change list, every single ``Place`` -- weather it
|
||||||
|
has an associated ``Restaurant`` or not -- will be displayed. Adding
|
||||||
|
a ``Restaurant`` to a ``Place`` just means filling out the required
|
||||||
|
``Restaurant`` fields.
|
||||||
|
|
||||||
|
Admin options
|
||||||
|
=============
|
||||||
|
|
||||||
|
The ``admin`` field in the model tells Django how to construct the admin
|
||||||
|
interface for the object. The field is an instance of the ``meta.Admin``
|
||||||
|
object, which has the following options (of which only ``fields`` is required):
|
||||||
|
|
||||||
|
``date_hierarchy``
|
||||||
|
------------------
|
||||||
|
|
||||||
|
To allow filtering of objects in the admin by date, set ``date_hierarchy``
|
||||||
|
to the name of the field to filter by::
|
||||||
|
|
||||||
|
date_hierarchy = 'order_date'
|
||||||
|
|
||||||
|
``fields``
|
||||||
|
----------
|
||||||
|
|
||||||
|
A list of fieldsets to display on the admin page. Each fieldset is a 2-tuple:
|
||||||
|
``(name, field_options)``. The ``name`` is a string to name the field set,
|
||||||
|
and ``field_options`` is a dictionary of information about the fields to be
|
||||||
|
displayed in that fieldset. This dictionary has the following keys:
|
||||||
|
|
||||||
|
``fields``
|
||||||
|
A tuple of field names to display in this fieldset. To display
|
||||||
|
multiple fields on the same line, wrap those fields in their
|
||||||
|
own tuple.
|
||||||
|
|
||||||
|
This key is required in the dict.
|
||||||
|
|
||||||
|
``classes``
|
||||||
|
Extra CSS classes to apply to the fieldset. This is a simple
|
||||||
|
string; you can apply multiple classes by separating them with
|
||||||
|
spaces.
|
||||||
|
|
||||||
|
Two useful classes defined by the default stylesheet are ``collapse``
|
||||||
|
and ``wide``. Fieldsets with the ``collapse`` style will be
|
||||||
|
initially collapsed in the admin and replaced with a small "click
|
||||||
|
to expand" link. Fieldsets with the ``wide`` style will be given
|
||||||
|
extra horizontal space.
|
||||||
|
|
||||||
|
For example (taken from the ``core.flatfiles`` model)::
|
||||||
|
|
||||||
|
fields = (
|
||||||
|
(None, {
|
||||||
|
'fields': ('url', 'title', 'content', 'sites')
|
||||||
|
}),
|
||||||
|
('Advanced options', {
|
||||||
|
'classes': 'collapse',
|
||||||
|
'fields' : ('enable_comments', 'registration_required', 'template_name')
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
|
||||||
|
results in an admin that looks like:
|
||||||
|
|
||||||
|
.. image:: images/flatfiles_admin.png
|
||||||
|
|
||||||
|
``js``
|
||||||
|
------
|
||||||
|
|
||||||
|
Extra JavaScript files to link into the admin screen. This can be used to
|
||||||
|
tweak a given type of admin page in JS or to provide "quick links" to fill
|
||||||
|
in default values for certain fields.
|
||||||
|
|
||||||
|
``list_display``
|
||||||
|
----------------
|
||||||
|
|
||||||
|
List of fields to display on the list page in the admin.
|
||||||
|
|
||||||
|
There are a few special cases that do other things besides displaying the
|
||||||
|
contents of the given fields:
|
||||||
|
|
||||||
|
* If the field given has a relationship, that relationship is
|
||||||
|
followed and the ``repr()`` of the related object is displayed.
|
||||||
|
|
||||||
|
* If the field is a ``BooleanField``, a "on" or "off" icon will
|
||||||
|
be displayed instead of ``True`` or ``False``.
|
||||||
|
|
||||||
|
* If the field name given does not exist, a function of the model
|
||||||
|
will be searched for and called if present. This function
|
||||||
|
should have a ``short_description`` attribute that will be
|
||||||
|
used as the header for the field.
|
||||||
|
|
||||||
|
See the exmaple below.
|
||||||
|
|
||||||
|
``list_filter``
|
||||||
|
---------------
|
||||||
|
|
||||||
|
List of fields to filter by. Each field should either be a ``BooleanField``
|
||||||
|
or else a field with a ``ManyToOne`` relation.
|
||||||
|
|
||||||
|
An example of how ``list_display`` and ``list_filter`` work (taken from
|
||||||
|
the ``auth.user`` model)::
|
||||||
|
|
||||||
|
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff'),
|
||||||
|
list_filter = ('is_staff', 'is_superuser'),
|
||||||
|
|
||||||
|
results in a admin that looks like:
|
||||||
|
|
||||||
|
.. image:: images/users_changelist.png
|
||||||
|
|
||||||
|
(This example also has ``search_fields`` defined; see below).
|
||||||
|
|
||||||
|
``ordering``
|
||||||
|
------------
|
||||||
|
|
||||||
|
An ordering tuple (see the `Options for models`_, above) that gives a
|
||||||
|
different ordering for the admin change list. If not given, the
|
||||||
|
model's default ordering will be used.
|
||||||
|
|
||||||
|
``save_as``
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Enables a "save as" feature on object pages. Normally, objects have
|
||||||
|
three save options: "Save", "Save and continue editing", and "Save
|
||||||
|
and add another". If ``save_as`` is ``True``, "Save and add another"
|
||||||
|
will be replaced by a "Save as" button.
|
||||||
|
|
||||||
|
``save_on_top``
|
||||||
|
---------------
|
||||||
|
|
||||||
|
If this option is ``True``, object pages will have the save buttons
|
||||||
|
across the top as well as at the bottom of the page.
|
||||||
|
|
||||||
|
``search_fields``
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
A list of fields to provide a text search for. These fields should,
|
||||||
|
obviously, be some kind of text field.
|
||||||
|
|
|
@ -0,0 +1,804 @@
|
||||||
|
============================
|
||||||
|
The Django template language
|
||||||
|
============================
|
||||||
|
|
||||||
|
Django's template language is designed to strike a balance between power and
|
||||||
|
ease; it's designed to feel comfortable to those used to working with HTML. If
|
||||||
|
you have any exposure to other text-based template languages like Smarty_ or
|
||||||
|
CheetahTemplate_, you should feel right at home with Django's templates.
|
||||||
|
|
||||||
|
.. _Smarty: http://smarty.php.net/
|
||||||
|
.. _CheetahTemplate: http://www.cheetahtemplate.org/
|
||||||
|
|
||||||
|
What's a template?
|
||||||
|
==================
|
||||||
|
|
||||||
|
A template is simply a text file. All Django templates by convention have
|
||||||
|
".html" extensions, but they can actually generate any text-based format (HTML,
|
||||||
|
XML, CSV, etc.).
|
||||||
|
|
||||||
|
To actually be useful, a template will contain **variables**, which get replaced
|
||||||
|
with values from the database when the template is evaluated, and **tags**,
|
||||||
|
which control the logic of the template.
|
||||||
|
|
||||||
|
Below is a minimal template that I'll be using to illustrate the parts of a template throughout this introduction::
|
||||||
|
|
||||||
|
{% extends base_generic %}
|
||||||
|
|
||||||
|
{% block title %}{{ section.title }}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<h1>{{ section.title }}</h1>
|
||||||
|
|
||||||
|
{% for story in story_list %}
|
||||||
|
<h2>
|
||||||
|
<a href="{{ story.get_absolute_url }}">
|
||||||
|
{{ story.headline|upper }}
|
||||||
|
</a>
|
||||||
|
</h2>
|
||||||
|
<p>{{ story.tease|truncatewords:"100" }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
What's a variable?
|
||||||
|
==================
|
||||||
|
|
||||||
|
Variables look like this: ``{{ variable }}``. When the template engine
|
||||||
|
encounters a variable, it evaluates that variable and replaces the variable with
|
||||||
|
the result. Many variables will be structures with named attributes; you can
|
||||||
|
"drill down" into these structures with dots (``.``), so in the above example ``
|
||||||
|
{{ section.title }}`` will be replaces with the ``title`` attribute of the
|
||||||
|
``section`` object.
|
||||||
|
|
||||||
|
If you use a variable that doesn't exist, it will be silently ignored; the
|
||||||
|
variable will be replaced by nothingness.
|
||||||
|
|
||||||
|
See `Using the built-in reference`_, below, for help on finding what variables
|
||||||
|
are available in a given template.
|
||||||
|
|
||||||
|
Variables may be modified before being displayed by **filters**.
|
||||||
|
|
||||||
|
What's a filter?
|
||||||
|
================
|
||||||
|
|
||||||
|
Filters look like this: ``{{ name|lower }}``. This display the value of the
|
||||||
|
``{{ name }}`` variable after being filtered through the ``lower`` filter which,
|
||||||
|
as you might have guessed, lowercases the text passed through it.
|
||||||
|
|
||||||
|
We use the pipe character to apply filters to emphasize the analogy with filters
|
||||||
|
on a water pipe: text enters one side, has some operation performed on it, and
|
||||||
|
"flows" out the other side. Stretching the analogy to the breaking point,
|
||||||
|
filters may be "chained"; the output of one filter applied to the next: ``{{
|
||||||
|
text|escape|linebreaks }}`` is a common idiom for escaping text contents and
|
||||||
|
then converting line breaks to ``<p>`` tags.
|
||||||
|
|
||||||
|
Certain filters take arguments; a filter argument looks like this: ``{{
|
||||||
|
bio|truncatewords:"30" }}``. This will display the first 30 words of the
|
||||||
|
``bio`` variable. Filter arguments always are in double quotes.
|
||||||
|
|
||||||
|
The `Built-in filter reference`_ below describes all the built-in filters.
|
||||||
|
|
||||||
|
What's a tag?
|
||||||
|
=============
|
||||||
|
|
||||||
|
Tags look like this: ``{% tag %}``. Tags are much more complex than variables:
|
||||||
|
some create text in the output; some control flow by performing loops, or logic;
|
||||||
|
some load external information into the template to be used by later variables.
|
||||||
|
|
||||||
|
Some tags are "block" tags with matching beginning and ending tags (i.e. ``{% tag %} ... tag contents ... {% endtag %}``. The `Built-in tag reference`_ below describes all the built-in tags.
|
||||||
|
|
||||||
|
Template Inheritance
|
||||||
|
====================
|
||||||
|
|
||||||
|
The most powerful -- and thus the most complex -- part of Django's template
|
||||||
|
engine is template inheritance. In a nutshell, template inheritance allows you
|
||||||
|
to build a base "skeleton" template that contains all the common elements of
|
||||||
|
your site and defines **blocks** that child templates can override.
|
||||||
|
|
||||||
|
It's easiest to understand template inheritance by starting with an example::
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
<title>{% block title %}My Amazing Site{% endblock %}</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="sidebar">
|
||||||
|
{% block sidebar %}
|
||||||
|
<ul>
|
||||||
|
<li><a href="/">Home</a></li>
|
||||||
|
<li><a href="/blog/">Blog</a></li>
|
||||||
|
</ul>
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
This template, which we'll call ``base.html`` defines a simple HTML skeleton
|
||||||
|
document that you might use for a simple two-column page. Since this template
|
||||||
|
won't actually be used directly, I've used the ``{% block %}`` tag to define the
|
||||||
|
three blocks that child templates will fill in. All that the ``block`` tag does
|
||||||
|
is to signal to the template engine that a child template may override those
|
||||||
|
portions of the template.
|
||||||
|
|
||||||
|
To use this template, I might define a child template as follows::
|
||||||
|
|
||||||
|
{% extends "base" %}
|
||||||
|
|
||||||
|
{% block title %}My Amazing Blog{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
{% for entry in blog_entries %}
|
||||||
|
<h2>{{ entry.title }}</h2>
|
||||||
|
<p>{{ entry.body }}</p>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
The ``{% extends %}`` tag is the key here; it tells the template engine that
|
||||||
|
this template "extends" another template. When this template is evaluated, the
|
||||||
|
first step the template engine will perform is to locate the parent template --
|
||||||
|
in this case, "base" (note the dropping of the ".html" extension). At that
|
||||||
|
point, the template engine will notice the three blocks in ``base.html``, and
|
||||||
|
replace those blocks with the contents of the child template. Depending on the
|
||||||
|
value of ``blog_entries``, the output might look like::
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
<title>My Amazing Blog</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="sidebar">
|
||||||
|
<ul>
|
||||||
|
<li><a href="/">Home</a></li>
|
||||||
|
<li><a href="/blog/">Blog</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
<h2>Entry one</h2>
|
||||||
|
<p>This is my first entry.</p>
|
||||||
|
|
||||||
|
<h2>Entry two</h2>
|
||||||
|
<p>This is my second entry.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
Note that since the child template did not define the ``sidebar`` block, the
|
||||||
|
value from the parent template is used instead.
|
||||||
|
|
||||||
|
Template inheritance does not have to be only single-level; multi-level
|
||||||
|
inheritance is possible, and indeed, quite useful.
|
||||||
|
|
||||||
|
Here are some tips for working with inheritance:
|
||||||
|
|
||||||
|
* More ``{% block %}`` tags in your base templates are better. Remember,
|
||||||
|
child templates do not have to define all parent blocks, so you can
|
||||||
|
fill in reasonable defaults in a number of blocks, then only define
|
||||||
|
the ones you need later on.
|
||||||
|
|
||||||
|
* If you find yourself reproducing the same content in a number of
|
||||||
|
documents, it probably means you should move that content to a
|
||||||
|
new ``{% block %}`` in a parent template.
|
||||||
|
|
||||||
|
* We often prefer to use three-level inheritance: a single base template
|
||||||
|
for the entire site, a set of mid-level templates for each section of
|
||||||
|
the site, and then the individual templates for each page. This
|
||||||
|
maximizes code reuse, and makes adding items to places like the
|
||||||
|
section-wide navigation possible.
|
||||||
|
|
||||||
|
* If you need to get the content of the block from the parent template,
|
||||||
|
the ``{{ block.super }}`` variable will do the trick. This is useful
|
||||||
|
if you want to add to the contents of a parent block instead of
|
||||||
|
completely overriding it.
|
||||||
|
|
||||||
|
Using the built-in reference
|
||||||
|
============================
|
||||||
|
|
||||||
|
Since Django can be used to develop any sort of site, the tags, filters, and
|
||||||
|
variables available will be different depending on the application. To make it
|
||||||
|
simple to figure out what's available in a given site.
|
||||||
|
|
||||||
|
This documentation is integrated into the administration interface for your
|
||||||
|
sites and is divided into 4 sections: tags, filters, models, and views. The
|
||||||
|
tags and filters sections describe all the built-in tags (in fact, the tag and
|
||||||
|
filter references below come directly from those pages) as well as any custom
|
||||||
|
tag or filter libraries available.
|
||||||
|
|
||||||
|
The views page is perhaps the most valuable. Each URL in your site has a
|
||||||
|
separate entry here, and clicking on a URL will show you:
|
||||||
|
|
||||||
|
* The name of the view function that generates that view.
|
||||||
|
* A short description of what the view does.
|
||||||
|
* The **context**, or each variable available in the view.
|
||||||
|
* The name of the template or templates that are used for that view.
|
||||||
|
|
||||||
|
The documentation page also has a bookmarklet that you can use to jump from any
|
||||||
|
page to the documentation page for that view.
|
||||||
|
|
||||||
|
Since most of Django revolves around database objects, the "models" section of
|
||||||
|
the documentation page describes each type of object in the system along with all
|
||||||
|
the fields available on that object.
|
||||||
|
|
||||||
|
Take together, the documentation pages should tell you every tag, filter,
|
||||||
|
variable and object available to you in a given template.
|
||||||
|
|
||||||
|
Custom tag and filter libraries
|
||||||
|
===============================
|
||||||
|
|
||||||
|
As mentioned above, certain applications will provide custom tag and filter
|
||||||
|
libraries. To use them, use the ``{% load %}`` tag::
|
||||||
|
|
||||||
|
{% load comments %}
|
||||||
|
|
||||||
|
{% comment_form for blogs.entries entry.id with is_public yes %}
|
||||||
|
|
||||||
|
In the above, the ``load`` tag loads the ``comments`` tag library, which then
|
||||||
|
makes the ``comment_form`` tag available for use. Consult the documentation
|
||||||
|
area in your admin to find the list of custom libraries in your installation.
|
||||||
|
|
||||||
|
Built-in tag and filter reference
|
||||||
|
=================================
|
||||||
|
|
||||||
|
For those without an admin site available, the reference for the stock tags and
|
||||||
|
filters follows. Since Django is highly customizable, the documentation
|
||||||
|
references in your admin should be considered the final word on these
|
||||||
|
tags/filters.
|
||||||
|
|
||||||
|
Built-in tag reference
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
block
|
||||||
|
`````
|
||||||
|
|
||||||
|
Define a block that can be overridden by child templates. See `Template
|
||||||
|
inheritance`_ for more information.
|
||||||
|
|
||||||
|
comment
|
||||||
|
```````
|
||||||
|
|
||||||
|
Ignore everything between ``{% comment %}`` and ``{% endcomment %}``
|
||||||
|
|
||||||
|
cycle
|
||||||
|
`````
|
||||||
|
|
||||||
|
Cycle among the given strings each time this tag is encountered.
|
||||||
|
|
||||||
|
Within a loop, cycles among the given strings each time through
|
||||||
|
the loop::
|
||||||
|
|
||||||
|
{% for o in some_list %}
|
||||||
|
<tr class="{% cycle row1,row2 %}">
|
||||||
|
...
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
Outside of a loop, give the values a unique name the first time you call it,
|
||||||
|
then use that name each successive time through::
|
||||||
|
|
||||||
|
<tr class="{% cycle row1,row2,row3 as rowcolors %}">...</tr>
|
||||||
|
<tr class="{% cycle rowcolors %}">...</tr>
|
||||||
|
<tr class="{% cycle rowcolors %}">...</tr>
|
||||||
|
|
||||||
|
You can use any number of values, separated by commas. Make sure not to put
|
||||||
|
spaces between the values -- only commas.
|
||||||
|
|
||||||
|
debug
|
||||||
|
`````
|
||||||
|
|
||||||
|
Output a whole load of debugging information, including the current context and
|
||||||
|
imported modules.
|
||||||
|
|
||||||
|
extends
|
||||||
|
```````
|
||||||
|
|
||||||
|
Signal that this template extends a parent template.
|
||||||
|
|
||||||
|
This tag may be used in two ways: ``{% extends "base" %}`` (with quotes) uses
|
||||||
|
the literal value "base" as the name of the parent template to extend, or ``{%
|
||||||
|
extends variable %}`` uses the value of ``variable`` as the name of the parent
|
||||||
|
template to extend.
|
||||||
|
|
||||||
|
See `Template inheritance`_ for more information.
|
||||||
|
|
||||||
|
filter
|
||||||
|
``````
|
||||||
|
|
||||||
|
Filter the contents of the blog through variable filters.
|
||||||
|
|
||||||
|
Filters can also be piped through each other, and they can have arguments --
|
||||||
|
just like in variable syntax.
|
||||||
|
|
||||||
|
Sample usage::
|
||||||
|
|
||||||
|
{% filter escape|lower %}
|
||||||
|
This text will be HTML-escaped, and will appear in all lowercase.
|
||||||
|
{% endfilter %}
|
||||||
|
|
||||||
|
firstof
|
||||||
|
```````
|
||||||
|
|
||||||
|
Outputs the first variable passed that is not False. Outputs nothing if all the
|
||||||
|
passed variables are False.
|
||||||
|
|
||||||
|
Sample usage::
|
||||||
|
|
||||||
|
{% firstof var1 var2 var3 %}
|
||||||
|
|
||||||
|
This is equivalent to::
|
||||||
|
|
||||||
|
{% if var1 %}
|
||||||
|
{{ var1 }}
|
||||||
|
{% else %}{% if var2 %}
|
||||||
|
{{ var2 }}
|
||||||
|
{% else %}{% if var3 %}
|
||||||
|
{{ var3 }}
|
||||||
|
{% endif %}{% endif %}{% endif %}
|
||||||
|
|
||||||
|
but obviously much cleaner!
|
||||||
|
|
||||||
|
for
|
||||||
|
```
|
||||||
|
|
||||||
|
Loop over each item in an array. For example, to display a list of athletes
|
||||||
|
given ``athlete_list``::
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{% for athlete in athlete_list %}
|
||||||
|
<li>{{ athlete.name }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
You can also loop over a list in reverse by using ``{% for obj in list reversed %}``.
|
||||||
|
|
||||||
|
The for loop sets a number of variables available within the loop:
|
||||||
|
|
||||||
|
========================== ================================================
|
||||||
|
Variable Description
|
||||||
|
========================== ================================================
|
||||||
|
``forloop.counter`` The current iteration of the loop (1-indexed)
|
||||||
|
``forloop.counter0`` The current iteration of the loop (0-indexed)
|
||||||
|
``forloop.first`` True if this is the first time through the loop
|
||||||
|
``forloop.last`` True if this is the last time through the loop
|
||||||
|
``forloop.parentloop`` For nested loops, this is the loop "above" the
|
||||||
|
current one
|
||||||
|
========================== ================================================
|
||||||
|
|
||||||
|
if
|
||||||
|
``
|
||||||
|
|
||||||
|
The ``{% if %}`` tag evaluates a variable, and if that variable is "true" (i.e.
|
||||||
|
exists, is not empty, and is not a false boolean value) the contents of the
|
||||||
|
block are output::
|
||||||
|
|
||||||
|
{% if athlete_list %}
|
||||||
|
Number of athletes: {{ athlete_list|count }}
|
||||||
|
{% else %}
|
||||||
|
No athletes.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
In the above, if ``athlete_list`` is not empty, the number of athletes will be
|
||||||
|
displayed by the ``{{ athlete_list|count }}`` variable.
|
||||||
|
|
||||||
|
As you can see, the ``if`` tag can take an option ``{% else %}`` clause that
|
||||||
|
will be displayed if the test fails.
|
||||||
|
|
||||||
|
``if`` tags may use ``or`` or ``not`` to test a number of variables or to negate
|
||||||
|
a given variable::
|
||||||
|
|
||||||
|
{% if not athlete_list %}
|
||||||
|
There are no athletes.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if athlete_list or coach_list %}
|
||||||
|
There are some athletes or some coaches.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not athlete_list or coach_list %}
|
||||||
|
There are no athletes or there are some coaches (OK, so
|
||||||
|
writing English translations of boolean logic sounds
|
||||||
|
stupid; it's not my fault).
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
For simplicity, ``if`` tags do not allow ``and`` clauses; use nested ``if``
|
||||||
|
tags instead::
|
||||||
|
|
||||||
|
{% if athlete_list %}
|
||||||
|
{% if coach_list %}
|
||||||
|
Number of athletes: {{ athlete_list|count }}.
|
||||||
|
Number of coaches: {{ coach_list|count }}.
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
ifchanged
|
||||||
|
`````````
|
||||||
|
|
||||||
|
Check if a value has changed from the last iteration of a loop.
|
||||||
|
|
||||||
|
The 'ifchanged' block tag is used within a loop. It checks its own rendered
|
||||||
|
contents against its previous state and only displays its content if the value
|
||||||
|
has changed::
|
||||||
|
|
||||||
|
<h1>Archive for {{ year }}</h1>
|
||||||
|
|
||||||
|
{% for date in days %}
|
||||||
|
{% ifchanged %}<h3>{{ date|date:"F" }}</h3>{% endifchanged %}
|
||||||
|
<a href="{{ date|date:"M/d"|lower }}/">{{ date|date:"j" }}</a>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
ifnotequal
|
||||||
|
``````````
|
||||||
|
|
||||||
|
Output the contents of the block if the two arguments do not equal each other.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
{% ifnotequal user.id_ comment.user_id %}
|
||||||
|
...
|
||||||
|
{% endifnotequal %}
|
||||||
|
|
||||||
|
load
|
||||||
|
````
|
||||||
|
|
||||||
|
Load a custom template tag set.
|
||||||
|
|
||||||
|
See `Custom tag and filter libraries`_ for more information.
|
||||||
|
|
||||||
|
now
|
||||||
|
```
|
||||||
|
|
||||||
|
Display the date, formatted according to the given string.
|
||||||
|
|
||||||
|
Uses the same format as PHP's ``date()`` function; see http://php.net/date
|
||||||
|
for all the possible values.
|
||||||
|
|
||||||
|
Sample usage::
|
||||||
|
|
||||||
|
It is {% now "jS F Y H:i" %}
|
||||||
|
|
||||||
|
regroup
|
||||||
|
```````
|
||||||
|
|
||||||
|
Regroup a list of alike objects by a common attribute.
|
||||||
|
|
||||||
|
This complex tag is best illustrated by use of an example: say that ``people``
|
||||||
|
is a list of ``Person`` objects that have ``first_name``, ``last_name``, and
|
||||||
|
``gender`` attributes, and you'd like to display a list that looks like:
|
||||||
|
|
||||||
|
* Male:
|
||||||
|
* George Bush
|
||||||
|
* Bill Clinton
|
||||||
|
* Female:
|
||||||
|
* Margaret Thatcher
|
||||||
|
* Colendeeza Rice
|
||||||
|
* Unknown:
|
||||||
|
* Janet Reno
|
||||||
|
|
||||||
|
The following snippet of template code would accomplish this dubious task::
|
||||||
|
|
||||||
|
{% regroup people by gender as grouped %}
|
||||||
|
<ul>
|
||||||
|
{% for group in grouped %}
|
||||||
|
<li>{{ group.grouper }}
|
||||||
|
<ul>
|
||||||
|
{% for item in group.list %}
|
||||||
|
<li>{{ item }}</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
As you can see, ``{% regroup %}`` populates a variable with a list of objects
|
||||||
|
with ``grouper`` and ``list`` attributes. ``grouper`` contains the item that
|
||||||
|
was grouped by; ``list`` contains the list of objects that share that
|
||||||
|
``grouper``. In this case, ``grouper`` would be ``Male``, ``Female`` and
|
||||||
|
``Unknown``, and ``list`` is the list of people with those genders.
|
||||||
|
|
||||||
|
Note that ``{% regroup %}`` does not work when the list to be grouped is not
|
||||||
|
sorted by the key you are grouping by! This means that if your list of people
|
||||||
|
was not sorted by gender, you'd need to make sure it is sorted before using it,
|
||||||
|
i.e.::
|
||||||
|
|
||||||
|
{% regroup people|dictsort:"gender" by gender as grouped %}
|
||||||
|
|
||||||
|
ssi
|
||||||
|
```
|
||||||
|
|
||||||
|
Output the contents of a given file into the page.
|
||||||
|
|
||||||
|
Like a simple "include" tag, the ``ssi`` tag includes the contents
|
||||||
|
of another file -- which must be specified using an absolute page --
|
||||||
|
in the current page::
|
||||||
|
|
||||||
|
{% ssi /home/html/ljworld.com/includes/right_generic.html %}
|
||||||
|
|
||||||
|
If the optional "parsed" parameter is given, the contents of the included
|
||||||
|
file are evaluated as template code, with the current context::
|
||||||
|
|
||||||
|
{% ssi /home/html/ljworld.com/includes/right_generic.html parsed %}
|
||||||
|
|
||||||
|
templatetag
|
||||||
|
```````````
|
||||||
|
|
||||||
|
Output one of the bits used to compose template tags.
|
||||||
|
|
||||||
|
Since the template system has no concept of "escaping", to display one of the
|
||||||
|
bits used in template tags, you must use the ``{% templatetag %}`` tag.
|
||||||
|
|
||||||
|
The argument tells which template bit to output:
|
||||||
|
|
||||||
|
================== =======
|
||||||
|
Argument Outputs
|
||||||
|
================== =======
|
||||||
|
``openblock`` ``{%``
|
||||||
|
``closeblock`` ``%}``
|
||||||
|
``openvariable`` ``{{``
|
||||||
|
``closevariable`` ``}}``
|
||||||
|
================== =======
|
||||||
|
|
||||||
|
widthratio
|
||||||
|
``````````
|
||||||
|
|
||||||
|
For creating bar charts and such, this tag calculates the ratio of a given value
|
||||||
|
to a maximum value, and then applies that ratio to a constant.
|
||||||
|
|
||||||
|
For example::
|
||||||
|
|
||||||
|
<img src='bar.gif' height='10' width='{% widthratio this_value max_value 100 %}' />
|
||||||
|
|
||||||
|
Above, if ``this_value`` is 175 and ``max_value`` is 200, the the image in the
|
||||||
|
above example will be 88 pixels wide (because 175/200 = .875; .875 * 100 = 87.5
|
||||||
|
which is rounded up to 88).
|
||||||
|
|
||||||
|
Built-in filter reference
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
add
|
||||||
|
```
|
||||||
|
Adds the arg to the value
|
||||||
|
|
||||||
|
addslashes
|
||||||
|
``````````
|
||||||
|
Adds slashes - useful for passing strings to JavaScript, for example.
|
||||||
|
|
||||||
|
capfirst
|
||||||
|
````````
|
||||||
|
Capitalizes the first character of the value
|
||||||
|
|
||||||
|
center
|
||||||
|
``````
|
||||||
|
Centers the value in a field of a given width
|
||||||
|
|
||||||
|
cut
|
||||||
|
```
|
||||||
|
Removes all values of arg from the given string
|
||||||
|
|
||||||
|
date
|
||||||
|
````
|
||||||
|
Formats a date according to the given format (same as the now_ tag)
|
||||||
|
|
||||||
|
default
|
||||||
|
```````
|
||||||
|
If value is unavailable, use given default
|
||||||
|
|
||||||
|
dictsort
|
||||||
|
````````
|
||||||
|
Takes a list of dicts, returns that list sorted by the property given in the
|
||||||
|
argument.
|
||||||
|
|
||||||
|
dictsortreversed
|
||||||
|
````````````````
|
||||||
|
Takes a list of dicts, returns that list sorted in reverse order by the property
|
||||||
|
given in the argument.
|
||||||
|
|
||||||
|
divisibleby
|
||||||
|
```````````
|
||||||
|
Returns true if the value is divisible by the argument
|
||||||
|
|
||||||
|
escape
|
||||||
|
``````
|
||||||
|
Escapes a string's HTML
|
||||||
|
|
||||||
|
filesizeformat
|
||||||
|
``````````````
|
||||||
|
Format the value like a 'human-readable' file size (i.e. 13 KB, 4.1 MB, 102
|
||||||
|
bytes, etc).
|
||||||
|
|
||||||
|
first
|
||||||
|
`````
|
||||||
|
Returns the first item in a list
|
||||||
|
|
||||||
|
fix_ampersands
|
||||||
|
``````````````
|
||||||
|
Replaces ampersands with ``&`` entities
|
||||||
|
|
||||||
|
floatformat
|
||||||
|
```````````
|
||||||
|
Displays a floating point number as 34.2 (with one decimal places) - but
|
||||||
|
only if there's a point to be displayed
|
||||||
|
|
||||||
|
get_digit
|
||||||
|
`````````
|
||||||
|
Given a whole number, returns the requested digit of it, where 1 is the
|
||||||
|
right-most digit, 2 is the second-right-most digit, etc. Returns the
|
||||||
|
original value for invalid input (if input or argument is not an integer,
|
||||||
|
or if argument is less than 1). Otherwise, output is always an integer.
|
||||||
|
|
||||||
|
join
|
||||||
|
````
|
||||||
|
Joins a list with a string, like Python's ``str.join(list)``
|
||||||
|
|
||||||
|
length
|
||||||
|
``````
|
||||||
|
Returns the length of the value - useful for lists
|
||||||
|
|
||||||
|
length_is
|
||||||
|
`````````
|
||||||
|
Returns a boolean of whether the value's length is the argument
|
||||||
|
|
||||||
|
linebreaks
|
||||||
|
``````````
|
||||||
|
Converts newlines into <p> and <br />s
|
||||||
|
|
||||||
|
linebreaksbr
|
||||||
|
````````````
|
||||||
|
Converts newlines into <br />s
|
||||||
|
|
||||||
|
linenumbers
|
||||||
|
```````````
|
||||||
|
Displays text with line numbers
|
||||||
|
|
||||||
|
ljust
|
||||||
|
`````
|
||||||
|
Left-aligns the value in a field of a given width
|
||||||
|
|
||||||
|
Argument: field size
|
||||||
|
|
||||||
|
lower
|
||||||
|
`````
|
||||||
|
Converts a string into all lowercase
|
||||||
|
|
||||||
|
make_list
|
||||||
|
`````````
|
||||||
|
Returns the value turned into a list. For an integer, it's a list of
|
||||||
|
digits. For a string, it's a list of characters.
|
||||||
|
|
||||||
|
phone2numeric
|
||||||
|
`````````````
|
||||||
|
Takes a phone number and converts it in to its numerical equivalent
|
||||||
|
|
||||||
|
pluralize
|
||||||
|
`````````
|
||||||
|
Returns 's' if the value is not 1, for '1 vote' vs. '2 votes'
|
||||||
|
|
||||||
|
pprint
|
||||||
|
``````
|
||||||
|
A wrapper around pprint.pprint -- for debugging, really
|
||||||
|
|
||||||
|
random
|
||||||
|
``````
|
||||||
|
Returns a random item from the list
|
||||||
|
|
||||||
|
removetags
|
||||||
|
```````````
|
||||||
|
Removes a space separated list of [X]HTML tags from the output
|
||||||
|
|
||||||
|
rjust
|
||||||
|
`````
|
||||||
|
Right-aligns the value in a field of a given width
|
||||||
|
|
||||||
|
Argument: field size
|
||||||
|
|
||||||
|
slice
|
||||||
|
`````
|
||||||
|
Returns a slice of the list.
|
||||||
|
|
||||||
|
Uses the same syntax as Python's list slicing; see
|
||||||
|
http://diveintopython.org/native_data_types/lists.html#odbchelper.list.slice
|
||||||
|
for an introduction.
|
||||||
|
|
||||||
|
slugify
|
||||||
|
```````
|
||||||
|
Converts to lowercase, removes non-alpha chars and converts spaces to hyphens
|
||||||
|
|
||||||
|
stringformat
|
||||||
|
````````````
|
||||||
|
Formats the variable according to the argument, a string formatting specifier.
|
||||||
|
This specifier uses Python string formating syntax, with the exception that
|
||||||
|
the leading "%" is dropped.
|
||||||
|
|
||||||
|
See http://docs.python.org/lib/typesseq-strings.html for documentation
|
||||||
|
of Python string formatting
|
||||||
|
|
||||||
|
striptags
|
||||||
|
`````````
|
||||||
|
Strips all [X]HTML tags
|
||||||
|
|
||||||
|
time
|
||||||
|
````
|
||||||
|
Formats a time according to the given format (same as the now_ tag).
|
||||||
|
|
||||||
|
timesince
|
||||||
|
`````````
|
||||||
|
Formats a date as the time since that date (i.e. "4 days, 6 hours")
|
||||||
|
|
||||||
|
title
|
||||||
|
`````
|
||||||
|
Converts a string into titlecase
|
||||||
|
|
||||||
|
truncatewords
|
||||||
|
`````````````
|
||||||
|
Truncates a string after a certain number of words
|
||||||
|
|
||||||
|
Argument: Number of words to truncate after
|
||||||
|
|
||||||
|
unordered_list
|
||||||
|
``````````````
|
||||||
|
Recursively takes a self-nested list and returns an HTML unordered list --
|
||||||
|
WITHOUT opening and closing <ul> tags.
|
||||||
|
|
||||||
|
The list is assumed to be in the proper format. For example, if ``var`` contains
|
||||||
|
``['States', [['Kansas', [['Lawrence', []], ['Topeka', []]]], ['Illinois', []]]]``,
|
||||||
|
then ``{{ var|unordered_list }}`` would return::
|
||||||
|
|
||||||
|
<li>States
|
||||||
|
<ul>
|
||||||
|
<li>Kansas
|
||||||
|
<ul>
|
||||||
|
<li>Lawrence</li>
|
||||||
|
<li>Topeka</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li>Illinois</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
upper
|
||||||
|
`````
|
||||||
|
Converts a string into all uppercase
|
||||||
|
|
||||||
|
urlencode
|
||||||
|
`````````
|
||||||
|
Escapes a value for use in a URL
|
||||||
|
|
||||||
|
urlize
|
||||||
|
``````
|
||||||
|
Converts URLs in plain text into clickable links
|
||||||
|
|
||||||
|
urlizetrunc
|
||||||
|
```````````
|
||||||
|
Converts URLs into clickable links, truncating URLs to the given character limit
|
||||||
|
|
||||||
|
Argument: Length to truncate URLs to.
|
||||||
|
|
||||||
|
wordcount
|
||||||
|
`````````
|
||||||
|
Returns the number of words
|
||||||
|
|
||||||
|
wordwrap
|
||||||
|
````````
|
||||||
|
Wraps words at specified line length
|
||||||
|
|
||||||
|
Argument: number of words to wrap the text at.
|
||||||
|
|
||||||
|
yesno
|
||||||
|
`````
|
||||||
|
Given a string mapping values for true, false and (optionally) None,
|
||||||
|
returns one of those strings according to the value:
|
||||||
|
|
||||||
|
========== ====================== ==================================
|
||||||
|
Value Argument Outputs
|
||||||
|
========== ====================== ==================================
|
||||||
|
``True`` ``"yeah,no,maybe"`` ``yeah``
|
||||||
|
``False`` ``"yeah,no,maybe"`` ``no``
|
||||||
|
``None`` ``"yeah,no,maybe"`` ``maybe``
|
||||||
|
``None`` ``"yeah,no"`` ``"no"`` (converts None to False
|
||||||
|
if no mapping for None is given.
|
||||||
|
========== ====================== ==================================
|
|
@ -0,0 +1,15 @@
|
||||||
|
- Getting started
|
||||||
|
- The application package structure
|
||||||
|
- INSTALLED_APPS
|
||||||
|
- Each step, explained tersely
|
||||||
|
- Writing models
|
||||||
|
- The model
|
||||||
|
- Admin specification
|
||||||
|
- Initializing the database
|
||||||
|
- Custom SQL
|
||||||
|
- Views
|
||||||
|
- URL dispatch
|
||||||
|
- View functions
|
||||||
|
- Request object
|
||||||
|
- Response objects
|
||||||
|
- Custom template tags/filters
|
Loading…
Reference in New Issue