summaryrefslogtreecommitdiff
path: root/docs/model-api.txt
diff options
context:
space:
mode:
authorJustin Bronn <jbronn@gmail.com>2007-08-26 01:10:53 +0000
committerJustin Bronn <jbronn@gmail.com>2007-08-26 01:10:53 +0000
commit2052b508eb92c62fc0678efd4936c5ec1e0e735b (patch)
treee510109b74b28c8ccef5f6955727cb9dce3da655 /docs/model-api.txt
parenta7297a255f4bb86f608ea251e00253d18c31d9d4 (diff)
gis: Made necessary modifications for unicode, manage refactor, backend refactor and merged 5584-6000 via svnmerge from [repos:django/trunk trunk].
git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6018 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs/model-api.txt')
-rw-r--r--docs/model-api.txt294
1 files changed, 223 insertions, 71 deletions
diff --git a/docs/model-api.txt b/docs/model-api.txt
index 22ff7445b5..0f872c3097 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -22,7 +22,7 @@ A companion to this document is the `official repository of model examples`_.
``tests/modeltests`` directory.)
.. _Database API reference: ../db-api/
-.. _official repository of model examples: http://www.djangoproject.com/documentation/models/
+.. _official repository of model examples: ../models/
Quick example
=============
@@ -33,8 +33,8 @@ This example model defines a ``Person``, which has a ``first_name`` and
from django.db import models
class Person(models.Model):
- first_name = models.CharField(maxlength=30)
- last_name = models.CharField(maxlength=30)
+ first_name = models.CharField(max_length=30)
+ last_name = models.CharField(max_length=30)
``first_name`` and ``last_name`` are *fields* of the model. Each field is
specified as a class attribute, and each attribute maps to a database column.
@@ -69,13 +69,13 @@ attributes.
Example::
class Musician(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
- instrument = models.CharField(maxlength=100)
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+ instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician)
- name = models.CharField(maxlength=100)
+ name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
@@ -142,14 +142,18 @@ For large amounts of text, use ``TextField``.
The admin represents this as an ``<input type="text">`` (a single-line input).
-``CharField`` has an extra required argument, ``maxlength``, the maximum length
-(in characters) of the field. The maxlength is enforced at the database level
+``CharField`` has an extra required argument, ``max_length``, the maximum length
+(in characters) of the field. The max_length is enforced at the database level
and in Django's validation.
+Django veterans: Note that the argument is now called ``max_length`` to
+provide consistency throughout Django. There is full legacy support for
+the old ``maxlength`` argument, but ``max_length`` is prefered.
+
``CommaSeparatedIntegerField``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A field of integers separated by commas. As in ``CharField``, the ``maxlength``
+A field of integers separated by commas. As in ``CharField``, the ``max_length``
argument is required.
``DateField``
@@ -217,7 +221,7 @@ The admin represents this as an ``<input type="text">`` (a single-line input).
~~~~~~~~~~~~~~
A ``CharField`` that checks that the value is a valid e-mail address.
-This doesn't accept ``maxlength``; its ``maxlength`` is automatically set to
+This doesn't accept ``max_length``; its ``max_length`` is automatically set to
75.
``FileField``
@@ -400,7 +404,7 @@ Like a ``PositiveIntegerField``, but only allows values under a certain
containing only letters, numbers, underscores or hyphens. They're generally
used in URLs.
-Like a CharField, you can specify ``maxlength``. If ``maxlength`` is
+Like a CharField, you can specify ``max_length``. If ``max_length`` is
not specified, Django will use a default length of 50.
Implies ``db_index=True``.
@@ -411,7 +415,8 @@ form::
models.SlugField(prepopulate_from=("pre_name", "name"))
-``prepopulate_from`` doesn't accept DateTimeFields.
+``prepopulate_from`` doesn't accept DateTimeFields, ForeignKeys nor
+ManyToManyFields.
The admin represents ``SlugField`` as an ``<input type="text">`` (a
single-line input).
@@ -447,9 +452,9 @@ 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
+``URLField`` takes an optional argument, ``max_length``, the maximum length (in
+characters) of the field. The maximum length is enforced at the database level and
+in Django's validation. If you don't specify ``max_length``, a default of 200
is used.
``USStateField``
@@ -536,7 +541,7 @@ The choices list can be defined either as part of your model class::
('M', 'Male'),
('F', 'Female'),
)
- gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
+ gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
or outside your model class altogether::
@@ -545,7 +550,7 @@ or outside your model class altogether::
('F', 'Female'),
)
class Foo(models.Model):
- gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
+ gender = models.CharField(max_length=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
@@ -620,6 +625,12 @@ Extra "help" text to be displayed under the field on the object's admin
form. It's useful for documentation even if your object doesn't have an
admin form.
+Note that this value is *not* HTML-escaped when it's displayed in the admin
+interface. This lets you include HTML in ``help_text`` if you so desire. For
+example::
+
+ help_text="Please use the following format: <em>YYYY-MM-DD</em>."
+
``primary_key``
~~~~~~~~~~~~~~~
@@ -698,11 +709,11 @@ it using the field's attribute name, converting underscores to spaces.
In this example, the verbose name is ``"Person's first name"``::
- first_name = models.CharField("Person's first name", maxlength=30)
+ first_name = models.CharField("Person's first name", max_length=30)
In this example, the verbose name is ``"first name"``::
- first_name = models.CharField(maxlength=30)
+ first_name = models.CharField(max_length=30)
``ForeignKey``, ``ManyToManyField`` and ``OneToOneField`` require the first
argument to be a model class, so use the ``verbose_name`` keyword argument::
@@ -727,7 +738,7 @@ Many-to-one relationships
To define a many-to-one relationship, use ``ForeignKey``. You use it just like
any other ``Field`` type: by including it as a class attribute of your model.
-``ForeignKey`` requires a positional argument: The class to which the model is
+``ForeignKey`` requires a positional argument: the class to which the model is
related.
For example, if a ``Car`` model has a ``Manufacturer`` -- that is, a
@@ -775,7 +786,7 @@ You can, of course, call the field whatever you want. For example::
See the `Many-to-one relationship model example`_ for a full example.
-.. _Many-to-one relationship model example: http://www.djangoproject.com/documentation/models/many_to_one/
+.. _Many-to-one relationship model example: ../models/many_to_one/
``ForeignKey`` fields take a number of extra arguments for defining how the
relationship should work. All are optional:
@@ -862,7 +873,7 @@ To define a many-to-many relationship, use ``ManyToManyField``. You use it just
like any other ``Field`` type: by including it as a class attribute of your
model.
-``ManyToManyField`` requires a positional argument: The class to which the
+``ManyToManyField`` requires a positional argument: the class to which the
model is related.
For example, if a ``Pizza`` has multiple ``Topping`` objects -- that is, a
@@ -902,7 +913,7 @@ set up above, the ``Pizza`` admin form would let users select the toppings.
See the `Many-to-many relationship model example`_ for a full example.
-.. _Many-to-many relationship model example: http://www.djangoproject.com/documentation/models/many_to_many/
+.. _Many-to-many relationship model example: ../models/many_to_many/
``ManyToManyField`` objects take a number of extra arguments for defining how
the relationship should work. All are optional:
@@ -959,7 +970,7 @@ model.
This is most useful on the primary key of an object when that object "extends"
another object in some way.
-``OneToOneField`` requires a positional argument: The class to which the
+``OneToOneField`` requires a positional argument: the class to which the
model is related.
For example, if you're building a database of "places", you would build pretty
@@ -979,7 +990,116 @@ as a read-only field when you edit an object in the admin interface:
See the `One-to-one relationship model example`_ for a full example.
-.. _One-to-one relationship model example: http://www.djangoproject.com/documentation/models/one_to_one/
+.. _One-to-one relationship model example: ../models/one_to_one/
+
+Custom field types
+------------------
+
+**New in Django development version**
+
+Django's built-in field types don't cover every possible database column type --
+only the common types, such as ``VARCHAR`` and ``INTEGER``. For more obscure
+column types, such as geographic polygons or even user-created types such as
+`PostgreSQL custom types`_, you can define your own Django ``Field`` subclasses.
+
+.. _PostgreSQL custom types: http://www.postgresql.org/docs/8.2/interactive/sql-createtype.html
+
+.. admonition:: Experimental territory
+
+ This is an area of Django that traditionally has not been documented, but
+ we're starting to include bits of documentation, one feature at a time.
+ Please forgive the sparseness of this section.
+
+ If you like living on the edge and are comfortable with the risk of
+ unstable, undocumented APIs, see the code for the core ``Field`` class
+ in ``django/db/models/fields/__init__.py`` -- but if/when the innards
+ change, don't say we didn't warn you.
+
+To create a custom field type, simply subclass ``django.db.models.Field``.
+Here is an incomplete list of the methods you should implement:
+
+``db_type()``
+~~~~~~~~~~~~~
+
+Returns the database column data type for the ``Field``, taking into account
+the current ``DATABASE_ENGINE`` setting.
+
+Say you've created a PostgreSQL custom type called ``mytype``. You can use this
+field with Django by subclassing ``Field`` and implementing the ``db_type()``
+method, like so::
+
+ from django.db import models
+
+ class MytypeField(models.Field):
+ def db_type(self):
+ return 'mytype'
+
+Once you have ``MytypeField``, you can use it in any model, just like any other
+``Field`` type::
+
+ class Person(models.Model):
+ name = models.CharField(max_length=80)
+ gender = models.CharField(max_length=1)
+ something_else = MytypeField()
+
+If you aim to build a database-agnostic application, you should account for
+differences in database column types. For example, the date/time column type
+in PostgreSQL is called ``timestamp``, while the same column in MySQL is called
+``datetime``. The simplest way to handle this in a ``db_type()`` method is to
+import the Django settings module and check the ``DATABASE_ENGINE`` setting.
+For example::
+
+ class MyDateField(models.Field):
+ def db_type(self):
+ from django.conf import settings
+ if settings.DATABASE_ENGINE == 'mysql':
+ return 'datetime'
+ else:
+ return 'timestamp'
+
+The ``db_type()`` method is only called by Django when the framework constructs
+the ``CREATE TABLE`` statements for your application -- that is, when you first
+create your tables. It's not called at any other time, so it can afford to
+execute slightly complex code, such as the ``DATABASE_ENGINE`` check in the
+above example.
+
+Some database column types accept parameters, such as ``CHAR(25)``, where the
+parameter ``25`` represents the maximum column length. In cases like these,
+it's more flexible if the parameter is specified in the model rather than being
+hard-coded in the ``db_type()`` method. For example, it wouldn't make much
+sense to have a ``CharMaxlength25Field``, shown here::
+
+ # This is a silly example of hard-coded parameters.
+ class CharMaxlength25Field(models.Field):
+ def db_type(self):
+ return 'char(25)'
+
+ # In the model:
+ class MyModel(models.Model):
+ # ...
+ my_field = CharMaxlength25Field()
+
+The better way of doing this would be to make the parameter specifiable at run
+time -- i.e., when the class is instantiated. To do that, just implement
+``__init__()``, like so::
+
+ # This is a much more flexible example.
+ class BetterCharField(models.Field):
+ def __init__(self, max_length, *args, **kwargs):
+ self.max_length = max_length
+ super(BetterCharField, self).__init__(*args, **kwargs)
+
+ def db_type(self):
+ return 'char(%s)' % self.max_length
+
+ # In the model:
+ class MyModel(models.Model):
+ # ...
+ my_field = BetterCharField(25)
+
+Note that if you implement ``__init__()`` on a ``Field`` subclass, it's
+important to call ``Field.__init__()`` -- i.e., the parent class'
+``__init__()`` method.
Meta options
============
@@ -987,7 +1107,7 @@ Meta options
Give your model metadata by using an inner ``class Meta``, like so::
class Foo(models.Model):
- bar = models.CharField(maxlength=30)
+ bar = models.CharField(max_length=30)
class Meta:
# ...
@@ -1077,7 +1197,7 @@ See `Specifying ordering`_ for more examples.
Note that, regardless of how many fields are in ``ordering``, the admin
site uses only the first field.
-.. _Specifying ordering: http://www.djangoproject.com/documentation/models/ordering/
+.. _Specifying ordering: ../models/ordering/
``permissions``
---------------
@@ -1161,8 +1281,8 @@ If you want your model to be visible to Django's admin site, give your model an
inner ``"class Admin"``, like so::
class Person(models.Model):
- first_name = models.CharField(maxlength=30)
- last_name = models.CharField(maxlength=30)
+ first_name = models.CharField(max_length=30)
+ last_name = models.CharField(max_length=30)
class Admin:
# Admin options go here
@@ -1302,8 +1422,8 @@ that displays the ``__str__()`` representation of each object.
A few special cases to note about ``list_display``:
- * If the field is a ``ForeignKey``, Django will display the ``__str__()``
- of the related object.
+ * If the field is a ``ForeignKey``, Django will display the
+ ``__unicode__()`` of the related object.
* ``ManyToManyField`` fields aren't supported, because that would entail
executing a separate SQL statement for each row in the table. If you
@@ -1321,7 +1441,7 @@ A few special cases to note about ``list_display``:
Here's a full example model::
class Person(models.Model):
- name = models.CharField(maxlength=50)
+ name = models.CharField(max_length=50)
birthday = models.DateField()
class Admin:
@@ -1338,9 +1458,9 @@ A few special cases to note about ``list_display``:
Here's a full example model::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
- color_code = models.CharField(maxlength=6)
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+ color_code = models.CharField(max_length=6)
class Admin:
list_display = ('first_name', 'last_name', 'colored_name')
@@ -1356,7 +1476,7 @@ A few special cases to note about ``list_display``:
Here's a full example model::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
+ first_name = models.CharField(max_length=50)
birthday = models.DateField()
class Admin:
@@ -1367,10 +1487,11 @@ A few special cases to note about ``list_display``:
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::
+ * The ``__str__()`` and ``__unicode__()`` methods are 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')
+ list_display = ('__unicode__', 'some_other_field')
* 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
@@ -1383,8 +1504,8 @@ A few special cases to note about ``list_display``:
For example::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- color_code = models.CharField(maxlength=6)
+ first_name = models.CharField(max_length=50)
+ color_code = models.CharField(max_length=6)
class Admin:
list_display = ('first_name', 'colored_first_name')
@@ -1552,7 +1673,7 @@ with an operator:
AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')
Note that the query input is split by spaces, so, following this example,
- it's not currently not possible to search for all records in which
+ it's currently not possible to search for all records in which
``first_name`` is exactly ``'john winston'`` (containing a space).
``@``
@@ -1634,13 +1755,13 @@ returns a list of all ``OpinionPoll`` objects, each with an extra
return result_list
class OpinionPoll(models.Model):
- question = models.CharField(maxlength=200)
+ question = models.CharField(max_length=200)
poll_date = models.DateField()
objects = PollManager()
class Response(models.Model):
poll = models.ForeignKey(Poll)
- person_name = models.CharField(maxlength=50)
+ person_name = models.CharField(max_length=50)
response = models.TextField()
With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return
@@ -1656,8 +1777,8 @@ A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
example, using this model::
class Book(models.Model):
- title = models.CharField(maxlength=100)
- author = models.CharField(maxlength=50)
+ title = models.CharField(max_length=100)
+ author = models.CharField(max_length=50)
...the statement ``Book.objects.all()`` will return all books in the database.
@@ -1675,8 +1796,8 @@ all objects, and one that returns only the books by Roald Dahl::
# Then hook it into the Book model explicitly.
class Book(models.Model):
- title = models.CharField(maxlength=100)
- author = models.CharField(maxlength=50)
+ title = models.CharField(max_length=100)
+ author = models.CharField(max_length=50)
objects = models.Manager() # The default manager.
dahl_objects = DahlBookManager() # The Dahl-specific manager.
@@ -1709,9 +1830,9 @@ For example::
return super(FemaleManager, self).get_query_set().filter(sex='F')
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
- sex = models.CharField(maxlength=1, choices=(('M', 'Male'), ('F', 'Female')))
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+ sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
people = models.Manager()
men = MaleManager()
women = FemaleManager()
@@ -1741,11 +1862,11 @@ model.
For example, this model has a few custom methods::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
birth_date = models.DateField()
- address = models.CharField(maxlength=100)
- city = models.CharField(maxlength=50)
+ address = models.CharField(max_length=100)
+ city = models.CharField(max_length=50)
state = models.USStateField() # Yes, this is America-centric...
def baby_boomer_status(self):
@@ -1776,20 +1897,47 @@ A few object methods have special meaning:
-----------
``__str__()`` is a Python "magic method" that defines what should be returned
-if you call ``str()`` on the object. Django uses ``str(obj)`` in a number of
-places, most notably as the value displayed to render an object in the Django
-admin site and as the value inserted into a template when it displays an
-object. Thus, you should always return a nice, human-readable string for the
-object's ``__str__``. Although this isn't required, it's strongly encouraged.
+if you call ``str()`` on the object. Django uses ``str(obj)`` (or the related
+function, ``unicode(obj)`` -- see below) in a number of places, most notably
+as the value displayed to render an object in the Django admin site and as the
+value inserted into a template when it displays an object. Thus, you should
+always return a nice, human-readable string for the object's ``__str__``.
+Although this isn't required, it's strongly encouraged (see the description of
+``__unicode__``, below, before putting ``_str__`` methods everywhere).
For example::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
def __str__(self):
- return '%s %s' % (self.first_name, self.last_name)
+ # Note use of django.utils.encoding.smart_str() here because
+ # first_name and last_name will be unicode strings.
+ return smart_str('%s %s' % (self.first_name, self.last_name))
+
+``__unicode__``
+---------------
+
+The ``__unicode__()`` method is called whenever you call ``unicode()`` on an
+object. Since Django's database backends will return Unicode strings in your
+model's attributes, you would normally want to write a ``__unicode__()``
+method for your model. The example in the previous section could be written
+more simply as::
+
+ class Person(models.Model):
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+
+ def __unicode__(self):
+ return u'%s %s' % (self.first_name, self.last_name)
+
+If you define a ``__unicode__()`` method on your model and not a ``__str__()``
+method, Django will automatically provide you with a ``__str__()`` that calls
+``__unicode()__`` and then converts the result correctly to a UTF-8 encoded
+string object. This is recommended development practice: define only
+``__unicode__()`` and let Django take care of the conversion to string objects
+when required.
``get_absolute_url``
--------------------
@@ -1805,10 +1953,12 @@ Django uses this in its admin interface. If an object defines
link that will jump you directly to the object's public view, according to
``get_absolute_url()``.
-Also, a couple of other bits of Django, such as the syndication-feed framework,
+Also, a couple of other bits of Django, such as the `syndication feed framework`_,
use ``get_absolute_url()`` as a convenience to reward people who've defined the
method.
+.. _syndication feed framework: ../syndication_feeds/
+
It's good practice to use ``get_absolute_url()`` in templates, instead of
hard-coding your objects' URLs. For example, this template code is bad::
@@ -1823,7 +1973,9 @@ But this template code is good::
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.
+ further processing. You may wish to use the
+ ``django.utils.encoding.iri_to_uri()`` function to help with this if you
+ are using unicode strings a lot.
.. _RFC 2396: http://www.ietf.org/rfc/rfc2396.txt
@@ -1841,7 +1993,7 @@ 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'),
+ (r'^people/(\d+)/$', 'people.views.details'),
...your model could have a ``get_absolute_url`` method that looked like this::
@@ -1864,8 +2016,8 @@ Similarly, if you had a URLconf entry that looked like::
'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.
+Notice that we specify an empty sequence for the second parameter in this case,
+because we only want to pass keyword parameters, not positional ones.
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
@@ -1917,7 +2069,7 @@ A classic use-case for overriding the built-in methods is if you want something
to happen whenever you save an object. For example::
class Blog(models.Model):
- name = models.CharField(maxlength=100)
+ name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self):
@@ -1928,7 +2080,7 @@ to happen whenever you save an object. For example::
You can also prevent saving::
class Blog(models.Model):
- name = models.CharField(maxlength=100)
+ name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self):