Kaydet (Commit) 8216abe7 authored tarafından Malcolm Tredinnick's avatar Malcolm Tredinnick

Documentation for creating custom model fields.


git-svn-id: http://code.djangoproject.com/svn/django/trunk@6652 bcc190cf-cafb-0310-a4f2-bffc1f526a37
üst ea100b60
This diff is collapsed.
......@@ -1013,111 +1013,12 @@ See the `One-to-one relationship model example`_ for a full example.
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)
If one of the existing model fields cannot be used to fit your purposes, or if
you wish to take advantage of some less common database column types, you can
create your own field class. Full coverage of creating your own fields is
provided in the `Custom Model Fields`_ documentation.
Note that if you implement ``__init__()`` on a ``Field`` subclass, it's
important to call ``Field.__init__()`` -- i.e., the parent class'
``__init__()`` method.
.. _Custom Model Fields: ../custom_model_fields/
Meta options
============
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment