summaryrefslogtreecommitdiff
path: root/docs/model-api.txt
diff options
context:
space:
mode:
Diffstat (limited to 'docs/model-api.txt')
-rw-r--r--docs/model-api.txt282
1 files changed, 215 insertions, 67 deletions
diff --git a/docs/model-api.txt b/docs/model-api.txt
index 1aa8c811f4..09440f2b56 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -21,7 +21,7 @@ A companion to this document is the `official repository of model examples`_.
(In the Django source distribution, these examples are in the
``tests/modeltests`` directory.)
-.. _Database API reference: http://www.djangoproject.com/documentation/db_api/
+.. _Database API reference: ../db-api/
.. _official repository of model examples: http://www.djangoproject.com/documentation/models/
Quick example
@@ -57,7 +57,7 @@ Some technical notes:
syntax, but it's worth noting Django uses SQL tailored to the database
backend specified in your `settings file`_.
-.. _settings file: http://www.djangoproject.com/documentation/settings/
+.. _settings file: ../settings/
Fields
======
@@ -94,7 +94,7 @@ Django places only two restrictions on model field names:
the way Django's query lookup syntax works. For example::
class Example(models.Model):
- foo__bar = models.IntegerField() 'foo__bar' has two underscores!
+ foo__bar = models.IntegerField() # 'foo__bar' has two underscores!
These limitations can be worked around, though, because your field name doesn't
necessarily have to match your database column name. See `db_column`_ below.
@@ -184,6 +184,35 @@ A date and time field. Takes the same extra options as ``DateField``.
The admin represents this as two ``<input type="text">`` fields, with
JavaScript shortcuts.
+``DecimalField``
+~~~~~~~~~~~~~~~~
+
+**New in Django development version**
+
+A fixed-precision decimal number, represented in Python by a ``Decimal`` instance.
+Has two **required** arguments:
+
+ ====================== ===================================================
+ Argument 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::
+
+ models.DecimalField(..., max_digits=5, decimal_places=2)
+
+And to store numbers up to approximately one billion with a resolution of 10
+decimal places::
+
+ models.DecimalField(..., max_digits=19, decimal_places=10)
+
+The admin represents this as an ``<input type="text">`` (a single-line input).
+
``EmailField``
~~~~~~~~~~~~~~
@@ -194,14 +223,23 @@ This doesn't accept ``maxlength``; its ``maxlength`` is automatically set to
``FileField``
~~~~~~~~~~~~~
-A file-upload field.
+A file-upload field. Has one **required** argument:
+
+ ====================== ===================================================
+ Argument Description
+ ====================== ===================================================
+ ``upload_to`` A local filesystem path that will be appended to
+ your ``MEDIA_ROOT`` setting to determine the
+ output of the ``get_<fieldname>_url()`` helper
+ function.
+ ====================== ===================================================
-Has an extra required argument, ``upload_to``, a local filesystem path to
-which files should be upload. 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).
+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).
-The admin represents this as an ``<input type="file">`` (a file-upload widget).
+The admin represents this field as an ``<input type="file">`` (a file-upload
+widget).
Using a ``FileField`` or an ``ImageField`` (see below) in a model takes a few
steps:
@@ -231,6 +269,13 @@ For example, say your ``MEDIA_ROOT`` is set to ``'/home/media'``, and
upload a file on Jan. 15, 2007, it will be saved in the directory
``/home/media/photos/2007/01/15``.
+If you want to retrieve the upload file's on-disk filename, or a URL that
+refers to that file, or the file's size, you can use the
+``get_FOO_filename()``, ``get_FOO_url()`` and ``get_FOO_size()`` methods.
+They are all documented here__.
+
+__ ../db-api/#get-foo-filename
+
Note that whenever you deal with uploaded files, you should pay close attention
to where you're uploading them and what type of files they are, to avoid
security holes. *Validate all uploaded files* so that you're sure the files are
@@ -246,7 +291,7 @@ visiting its URL on your site. Don't allow that.
A field whose choices are limited to the filenames in a certain directory
on the filesystem. Has three special arguments, of which the first is
-required:
+**required**:
====================== ===================================================
Argument Description
@@ -281,28 +326,16 @@ because the ``match`` applies to the base filename (``foo.gif`` and
``FloatField``
~~~~~~~~~~~~~~
-A floating-point number. Has two **required** arguments:
+**Changed in Django development version**
- ====================== ===================================================
- Argument Description
- ====================== ===================================================
- ``max_digits`` The maximum number of digits allowed in the number.
-
- ``decimal_places`` The number of decimal places to store with the
- number.
- ====================== ===================================================
+A floating-point number represented in Python by a ``float`` instance.
-For example, to store numbers up to 999 with a resolution of 2 decimal places,
-you'd use::
-
- models.FloatField(..., max_digits=5, decimal_places=2)
-
-And to store numbers up to approximately one billion with a resolution of 10
-decimal places::
+The admin represents this as an ``<input type="text">`` (a single-line input).
- models.FloatField(..., max_digits=19, decimal_places=10)
+**NOTE:** The semantics of ``FloatField`` have changed in the Django
+development version. See the `Django 0.96 documentation`_ for the old behavior.
-The admin represents this as an ``<input type="text">`` (a single-line input).
+.. _Django 0.96 documentation: http://www.djangoproject.com/documentation/0.96/model-api/#floatfield
``ImageField``
~~~~~~~~~~~~~~
@@ -312,9 +345,14 @@ 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 each time a model instance is saved.
+In addition to the special ``get_FOO_*`` methods that are available for
+``FileField``, an ``ImageField`` also has ``get_FOO_height()`` and
+``get_FOO_width()`` methods. These are documented elsewhere_.
+
Requires the `Python Imaging Library`_.
.. _Python Imaging Library: http://www.pythonware.com/products/pil/
+.. _elsewhere: ../db-api/#get-foo-height-and-get-foo-width
``IntegerField``
~~~~~~~~~~~~~~~~
@@ -362,9 +400,8 @@ Like a ``PositiveIntegerField``, but only allows values under a certain
containing only letters, numbers, underscores or hyphens. They're generally
used in URLs.
-In the Django development version, you can specify ``maxlength``. If
-``maxlength`` is not specified, Django will use a default length of 50. In
-previous Django versions, there's no way to override the length of 50.
+Like a CharField, you can specify ``maxlength``. If ``maxlength`` is
+not specified, Django will use a default length of 50.
Implies ``db_index=True``.
@@ -410,6 +447,11 @@ and doesn't give a 404 response).
The admin represents this as an ``<input type="text">`` (a single-line input).
+``URLField`` takes an optional argument, ``maxlength``, the maximum length (in
+characters) of the field. The maxlength is enforced at the database level and
+in Django's validation. If you don't specify ``maxlength``, a default of 200
+is used.
+
``USStateField``
~~~~~~~~~~~~~~~~
@@ -438,8 +480,10 @@ If ``True``, Django will store empty values as ``NULL`` in the database.
Default is ``False``.
Note that empty string values will always get stored as empty strings, not
-as ``NULL`` -- so use ``null=True`` for non-string fields such as integers,
-booleans and dates.
+as ``NULL``. Only use ``null=True`` for non-string fields such as integers,
+booleans and dates. For both types of fields, you will also need to set
+``blank=True`` if you wish to permit empty values in forms, as the ``null``
+parameter only affects database storage (see blank_, below).
Avoid using ``null`` on string-based fields such as ``CharField`` and
``TextField`` unless you have an excellent reason. If a string-based field
@@ -451,7 +495,7 @@ string, not ``NULL``.
``blank``
~~~~~~~~~
-If ``True``, the field is allowed to be blank.
+If ``True``, the field is allowed to be blank. Default is ``False``.
Note that this is different than ``null``. ``null`` is purely
database-related, whereas ``blank`` is validation-related. If a field has
@@ -498,6 +542,12 @@ or outside your model class altogether::
class Foo(models.Model):
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
+For each model field that has ``choices`` set, Django will add a method to
+retrieve the human-readable name for the field's current value. See
+`get_FOO_display`_ in the database API documentation.
+
+.. _get_FOO_display: ../db-api/#get-foo-display
+
Finally, note that choices can be any iterable object -- not necessarily a
list or tuple. This lets you construct choices dynamically. But if you find
yourself hacking ``choices`` to be dynamic, you're probably better off using
@@ -621,7 +671,7 @@ that takes the parameters ``field_data, all_data`` and raises
Django comes with quite a few validators. They're in ``django.core.validators``.
-.. _validator docs: http://www.djangoproject.com/documentation/forms/#validators
+.. _validator docs: ../forms/#validators
Verbose field names
-------------------
@@ -729,10 +779,10 @@ relationship should work. All are optional:
``limit_choices_to`` A dictionary of lookup arguments and values (see
the `Database API reference`_) that limit the
available admin choices for this object. Use this
- with ``models.LazyDate`` to limit choices of objects
- by date. For example::
+ with functions from the Python ``datetime`` module
+ to limit choices of objects by date. For example::
- limit_choices_to = {'pub_date__lte': models.LazyDate()}
+ limit_choices_to = {'pub_date__lte': datetime.now}
only allows the choice of related objects with a
``pub_date`` before the current date/time to be
@@ -787,8 +837,8 @@ relationship should work. All are optional:
the related object.
======================= ============================================================
-.. _`Database API reference`: http://www.djangoproject.com/documentation/db_api/
-.. _related objects documentation: http://www.djangoproject.com/documentation/db_api/#related-objects
+.. _`Database API reference`: ../db-api/
+.. _related objects documentation: ../db-api/#related-objects
Many-to-many relationships
~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -875,6 +925,10 @@ the relationship should work. All are optional:
relationship, allowing ``ManyToMany`` relationships to be
non-symmetrical.
+ ``db_table`` The name of the table to create for storing the many-to-many
+ data. If this is not provided, Django will assume a default
+ name based upon the names of the two tables being joined.
+
======================= ============================================================
One-to-one relationships
@@ -954,7 +1008,7 @@ Example::
See the `docs for latest()`_ for more.
-.. _docs for latest(): http://www.djangoproject.com/documentation/db_api/#latest-field-name-none
+.. _docs for latest(): ../db-api/#latest-field-name-none
``order_with_respect_to``
-------------------------
@@ -1206,6 +1260,10 @@ screen via ``<script src="">`` tags. This can be used to tweak a given type of
admin page in JavaScript or to provide "quick links" to fill in default values
for certain fields.
+If you use relative URLs -- URLs that don't start with ``http://`` or ``/`` --
+then the admin site will automatically prefix these links with
+``settings.ADMIN_MEDIA_PREFIX``.
+
``list_display``
----------------
@@ -1268,15 +1326,53 @@ A few special cases to note about ``list_display``:
return '<span style="color: #%s;">%s %s</span>' % (self.color_code, self.first_name, self.last_name)
colored_name.allow_tags = True
+ * If the string given is a method of the model that returns True or False
+ Django will display a pretty "on" or "off" icon if you give the method a
+ ``boolean`` attribute whose value is ``True``.
+
+ Here's a full example model::
+
+ class Person(models.Model):
+ first_name = models.CharField(maxlength=50)
+ birthday = models.DateField()
+
+ class Admin:
+ list_display = ('name', 'born_in_fifties')
+
+ def born_in_fifties(self):
+ return self.birthday.strftime('%Y')[:3] == 5
+ born_in_fifties.boolean = True
+
+
* The ``__str__()`` method is just as valid in ``list_display`` as any
other model method, so it's perfectly OK to do this::
list_display = ('__str__', 'some_other_field')
- * For any element of ``list_display`` that is not a field on the model, the
- change list page will not allow ordering by that column. This is because
- ordering is done at the database level, and Django has no way of knowing
- how to order the result of a custom method at the SQL level.
+ * Usually, elements of ``list_display`` that aren't actual database fields
+ can't be used in sorting (because Django does all the sorting at the
+ database level).
+
+ However, if an element of ``list_display`` represents a certain database
+ field, you can indicate this fact by setting the ``admin_order_field``
+ attribute of the item.
+
+ For example::
+
+ class Person(models.Model):
+ first_name = models.CharField(maxlength=50)
+ color_code = models.CharField(maxlength=6)
+
+ class Admin:
+ list_display = ('first_name', 'colored_first_name')
+
+ def colored_first_name(self):
+ return '<span style="color: #%s;">%s</span>' % (self.color_code, self.first_name)
+ colored_first_name.allow_tags = True
+ colored_first_name.admin_order_field = 'first_name'
+
+ The above will tell Django to order by the ``first_name`` field when
+ trying to sort by ``colored_first_name`` in the admin.
``list_display_links``
----------------------
@@ -1346,7 +1442,7 @@ if one of the ``list_display`` fields is a ``ForeignKey``.
For more on ``select_related()``, see `the select_related() docs`_.
-.. _the select_related() docs: http://www.djangoproject.com/documentation/db_api/#select-related
+.. _the select_related() docs: ../db-api/#select-related
``ordering``
------------
@@ -1390,7 +1486,10 @@ This should be set to a list of field names that will be searched whenever
somebody submits a search query in that text box.
These fields should be some kind of text field, such as ``CharField`` or
-``TextField``.
+``TextField``. You can also perform a related lookup on a ``ForeignKey`` with
+the lookup API "follow" notation::
+
+ search_fields = ['foreign_key__related_fieldname']
When somebody does a search in the admin search box, Django splits the search
query into words and returns all objects that contain each of the words, case
@@ -1402,8 +1501,8 @@ user searches for ``john lennon``, Django will do the equivalent of this SQL
WHERE (first_name ILIKE '%john%' OR last_name ILIKE '%john%')
AND (first_name ILIKE '%lennon%' OR last_name ILIKE '%lennon%')
-**New in Django development version:** For faster and/or more restrictive
-searches, prefix the field name with an operator:
+For faster and/or more restrictive searches, prefix the field name
+with an operator:
``^``
Matches the beginning of the field. For example, if ``search_fields`` is
@@ -1448,7 +1547,7 @@ The way ``Manager`` classes work is documented in the `Retrieving objects`_
section of the database API docs, but this section specifically touches on
model options that customize ``Manager`` behavior.
-.. _Retrieving objects: http://www.djangoproject.com/documentation/db_api/#retrieving-objects
+.. _Retrieving objects: ../db-api/#retrieving-objects
Manager names
-------------
@@ -1696,11 +1795,58 @@ But this template code is good::
<a href="{{ object.get_absolute_url }}">{{ object.name }}</a>
-(Yes, we know ``get_absolute_url()`` couples URLs to models, which violates the
-DRY principle, because URLs are defined both in a URLconf and in the model.
-This is a rare case in which we've intentionally violated that principle for
-the sake of convenience. With that said, we're working on an even cleaner way
-of specifying URLs in a more DRY fashion.)
+.. note::
+ The string you return from ``get_absolute_url()`` must contain only ASCII
+ characters (required by the URI spec, `RFC 2396`_) that have been
+ URL-encoded, if necessary. Code and templates using ``get_absolute_url()``
+ should be able to use the result directly without needing to do any
+ further processing.
+
+.. _RFC 2396: http://www.ietf.org/rfc/rfc2396.txt
+
+The ``permalink`` decorator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The problem with the way we wrote ``get_absolute_url()`` above is that it
+slightly violates the DRY principle: the URL for this object is defined both
+in the URLConf file and in the model.
+
+You can further decouple your models from the URLconf using the ``permalink``
+decorator. This decorator is passed the view function, a list of positional
+parameters and (optionally) a dictionary of named parameters. Django then
+works out the correct full URL path using the URLconf, substituting the
+parameters you have given into the URL. For example, if your URLconf
+contained a line such as::
+
+ (r'^/people/(\d+)/$', 'people.views.details'),
+
+...your model could have a ``get_absolute_url`` method that looked like this::
+
+ from django.db.models import permalink
+
+ def get_absolute_url(self):
+ return ('people.views.details', [str(self.id)])
+ get_absolute_url = permalink(get_absolute_url)
+
+Similarly, if you had a URLconf entry that looked like::
+
+ (r'/archive/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/$', archive_view)
+
+...you could reference this using ``permalink()`` as follows::
+
+ def get_absolute_url(self):
+ return ('archive_view', (), {
+ 'year': self.created.year,
+ 'month': self.created.month,
+ 'day': self.created.day})
+ get_absolute_url = permalink(get_absolute_url)
+
+Notice that we specify an empty sequence for the second argument in this case,
+because we only want to pass keyword arguments, not named arguments.
+
+In this way, you're tying the model's absolute URL to the view that is used
+to display it, without repeating the URL information anywhere. You can still
+use the ``get_absolute_url`` method in templates, as before.
Executing custom SQL
--------------------
@@ -1719,21 +1865,23 @@ rows. Example::
row = cursor.fetchone()
return row
-``connection`` and ``cursor`` simply use the standard `Python DB-API`_. If
-you're not familiar with the Python DB-API, note that the SQL statement in
-``cursor.execute()`` uses placeholders, ``"%s"``, rather than adding parameters
-directly within the SQL. If you use this technique, the underlying database
-library will automatically add quotes and escaping to your parameter(s) as
-necessary. (Also note that Django expects the ``"%s"`` placeholder, *not* the
-``"?"`` placeholder, which is used by the SQLite Python bindings. This is for
-the sake of consistency and sanity.)
+``connection`` and ``cursor`` mostly implement the standard `Python DB-API`_
+(except when it comes to `transaction handling`_). If you're not familiar with
+the Python DB-API, note that the SQL statement in ``cursor.execute()`` uses
+placeholders, ``"%s"``, rather than adding parameters directly within the SQL.
+If you use this technique, the underlying database library will automatically
+add quotes and escaping to your parameter(s) as necessary. (Also note that
+Django expects the ``"%s"`` placeholder, *not* the ``"?"`` placeholder, which is
+used by the SQLite Python bindings. This is for the sake of consistency and
+sanity.)
A final note: If all you want to do is a custom ``WHERE`` clause, you can just
just the ``where``, ``tables`` and ``params`` arguments to the standard lookup
API. See `Other lookup options`_.
.. _Python DB-API: http://www.python.org/peps/pep-0249.html
-.. _Other lookup options: http://www.djangoproject.com/documentation/db_api/#extra-params-select-where-tables
+.. _Other lookup options: ../db-api/#extra-params-select-where-tables
+.. _transaction handling: ../transactions/
Overriding default model methods
--------------------------------
@@ -1766,7 +1914,7 @@ You can also prevent saving::
else:
super(Blog, self).save() # Call the "real" save() method.
-.. _database API docs: http://www.djangoproject.com/documentation/db_api/
+.. _database API docs: ../db-api/
Models across files
===================
@@ -1823,7 +1971,7 @@ Each SQL file, if given, is expected to contain valid SQL. The SQL files are
piped directly into the database after all of the models' table-creation
statements have been executed.
-The SQL files are read by the ``sqlinitialdata``, ``sqlreset``, ``sqlall`` and
+The SQL files are read by the ``sqlcustom``, ``sqlreset``, ``sqlall`` and
``reset`` commands in ``manage.py``. Refer to the `manage.py documentation`_
for more information.
@@ -1832,7 +1980,7 @@ order in which they're executed. The only thing you can assume is that, by the
time your custom data files are executed, all the database tables already will
have been created.
-.. _`manage.py documentation`: http://www.djangoproject.com/documentation/django_admin/#sqlinitialdata-appname-appname
+.. _`manage.py documentation`: ../django-admin/#sqlcustom-appname-appname
Database-backend-specific SQL data
----------------------------------