diff options
Diffstat (limited to 'docs')
| -rwxr-xr-x | docs/build.py | 48 | ||||
| -rw-r--r-- | docs/db-api.txt | 258 | ||||
| -rw-r--r-- | docs/images/flatfiles_admin.png | bin | 0 -> 42243 bytes | |||
| -rw-r--r-- | docs/images/users_changelist.png | bin | 0 -> 59355 bytes | |||
| -rw-r--r-- | docs/model-api.txt | 760 | ||||
| -rw-r--r-- | docs/templates.txt | 804 | ||||
| -rw-r--r-- | docs/writing-apps-guide-outline.txt | 15 |
7 files changed, 1885 insertions, 0 deletions
diff --git a/docs/build.py b/docs/build.py new file mode 100755 index 0000000000..29b5c5add4 --- /dev/null +++ b/docs/build.py @@ -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()]) diff --git a/docs/db-api.txt b/docs/db-api.txt new file mode 100644 index 0000000000..aebfd36cfa --- /dev/null +++ b/docs/db-api.txt @@ -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 +==================== + diff --git a/docs/images/flatfiles_admin.png b/docs/images/flatfiles_admin.png Binary files differnew file mode 100644 index 0000000000..391a629348 --- /dev/null +++ b/docs/images/flatfiles_admin.png diff --git a/docs/images/users_changelist.png b/docs/images/users_changelist.png Binary files differnew file mode 100644 index 0000000000..d5f9c016cc --- /dev/null +++ b/docs/images/users_changelist.png diff --git a/docs/model-api.txt b/docs/model-api.txt new file mode 100644 index 0000000000..b794da2678 --- /dev/null +++ b/docs/model-api.txt @@ -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. + diff --git a/docs/templates.txt b/docs/templates.txt new file mode 100644 index 0000000000..72b863513c --- /dev/null +++ b/docs/templates.txt @@ -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. +========== ====================== ================================== diff --git a/docs/writing-apps-guide-outline.txt b/docs/writing-apps-guide-outline.txt new file mode 100644 index 0000000000..a2d8c7e010 --- /dev/null +++ b/docs/writing-apps-guide-outline.txt @@ -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 |
