Documente Academic
Documente Profesional
Documente Cultură
your model attributes. The model attributes contain normal Python objects. The
field classes you define in a model are actually stored in the ``Meta`` class
when the model class is created (the precise details of how this is done are
unimportant here). This is because the field classes aren't necessary when
you're just creating and modifying attributes. Instead, they provide the
machinery for converting between the attribute value and what is stored in the
database or sent to the :doc:`serializer </topics/serialization>`.
Keep this in mind when creating your own custom fields. The Django ``Field``
subclass you write provides the machinery for converting between your Python
instances and the database/serializer values in various ways (there are
differences between storing a value and using a value for lookups, for
example). If this sounds a bit tricky, don't worry -- it will become clearer in
the examples below. Just remember that you will often end up creating two
classes when you want a custom field:
* The first class is the Python object that your users will manipulate.
They will assign it to the model attribute, they will read from it for
displaying purposes, things like that. This is the ``Hand`` class in our
example.
* The second class is the ``Field`` subclass. This is the class that knows
how to convert your first class back and forth between its permanent
storage form and the Python form.
Writing a field subclass
========================
When planning your :class:`~django.db.models.Field` subclass, first give some
thought to which existing :class:`~django.db.models.Field` class your new field
is most similar to. Can you subclass an existing Django field and save yourself
some work? If not, you should subclass the :class:`~django.db.models.Field`
class, from which everything is descended.
Initializing your new field is a matter of separating out any arguments that are
specific to your case from the common arguments and passing the latter to the
``__init__()`` method of :class:`~django.db.models.Field` (or your parent
class).
In our example, we'll call our field ``HandField``. (It's a good idea to call
your :class:`~django.db.models.Field` subclass ``<Something>Field``, so it's
easily identifiable as a :class:`~django.db.models.Field` subclass.) It doesn't
behave like any existing field, so we'll subclass directly from
:class:`~django.db.models.Field`::
from django.db import models
class HandField(models.Field):
description = "A hand of cards (bridge style)"
def __init__(self, *args, **kwargs):
kwargs['max_length'] = 104
super(HandField, self).__init__(*args, **kwargs)
Our ``HandField`` accepts most of the standard field options (see the list
below), but we ensure it has a fixed length, since it only needs to hold 52
card values plus their suits; 104 characters in total.
.. note::
Many of Django's model fields accept options that they don't do anything
with. For example, you can pass both
:attr:`~django.db.models.Field.editable` and
:attr:`~django.db.models.DateField.auto_now` to a
:class:`django.db.models.DateField` and it will simply ignore the
:attr:`~django.db.models.Field.editable` parameter
(:attr:`~django.db.models.DateField.auto_now` being set implies
``editable=False``). No error is raised in this case.
This behavior simplifies the field classes, because they don't need to
check for options that aren't necessary. They just pass all the options to
the parent class and then don't use them later on. It's up to you whether
you want your fields to be more strict about the options they select, or to
use the simpler, more permissive behavior of the current fields.
.. method:: Field.__init__
The :meth:`~django.db.models.Field.__init__` method takes the following
parameters:
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
:attr:`~django.db.models.Field.verbose_name`
``name``
:attr:`~django.db.models.Field.primary_key`
:attr:`~django.db.models.CharField.max_length`
:attr:`~django.db.models.Field.unique`
:attr:`~django.db.models.Field.blank`
:attr:`~django.db.models.Field.null`
:attr:`~django.db.models.Field.db_index`
``rel``: Used for related fields (like :class:`ForeignKey`). For advanced
use only.
:attr:`~django.db.models.Field.default`
:attr:`~django.db.models.Field.editable`
``serialize``: If ``False``, the field will not be serialized when the model
is passed to Django's :doc:`serializers </topics/serialization>`. Defaults to
``True``.
:attr:`~django.db.models.Field.unique_for_date`
:attr:`~django.db.models.Field.unique_for_month`
:attr:`~django.db.models.Field.unique_for_year`
:attr:`~django.db.models.Field.choices`
:attr:`~django.db.models.Field.help_text`
:attr:`~django.db.models.Field.db_column`
:attr:`~django.db.models.Field.db_tablespace`: Only for index creation, if the
backend supports :doc:`tablespaces </topics/db/tablespaces>`. You can usually
ignore this option.
``auto_created``: True if the field was
automatically created, as for the `OneToOneField` used by model
inheritance. For advanced use only.
All of the options without an explanation in the above list have the same
meaning they do for normal Django fields. See the :doc:`field documentation
</ref/models/fields>` for examples and details.
The ``SubfieldBase`` metaclass
-----------------------------.. class:: django.db.models.SubfieldBase
As we indicated in the introduction_, field subclasses are often needed for
two reasons: either to take advantage of a custom database column type, or to
In our ``HandField`` class, we're storing the data as a VARCHAR field in the
database, so we need to be able to process strings and ``Hand`` instances in
:meth:`.to_python`::
import re
class HandField(models.Field):
# ...
def to_python(self, value):
if isinstance(value, Hand):
return value
# The string case.
p1 = re.compile('.{26}')
p2 = re.compile('..')
args = [p2.findall(x) for x in p1.findall(value)]
if len(args) != 4:
raise ValidationError("Invalid input for a Hand instance")
return Hand(*args)
Notice that we always return a ``Hand`` instance from this method. That's the
Python object type we want to store in the model's attribute. If anything is
going wrong during value conversion, you should raise a
:exc:`~django.core.exceptions.ValidationError` exception.
**Remember:** If your custom field needs the :meth:`.to_python` method to be
called when it is created, you should be using `The SubfieldBase metaclass`_
mentioned earlier. Otherwise :meth:`.to_python` won't be called
automatically.
.. warning::
If your custom field allows ``null=True``, any field method that takes
``value`` as an argument, like :meth:`~Field.to_python` and
:meth:`~Field.get_prep_value`, should handle the case when ``value`` is
``None``.
Converting Python objects to query values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. method:: Field.get_prep_value(self, value)
This is the reverse of :meth:`.to_python` when working with the
database backends (as opposed to serialization). The ``value``
parameter is the current value of the model's attribute (a field has
no reference to its containing model, so it cannot retrieve the value
itself), and the method should return data in a format that has been
prepared for use as a parameter in a query.
This conversion should *not* include any database-specific
conversions. If database-specific conversions are required, they
should be made in the call to :meth:`.get_db_prep_value`.
For example::
class HandField(models.Field):
# ...
def get_prep_value(self, value):
used by the serializer, but the default :meth:`.db_type` method will return
``None``. See the documentation of :meth:`.db_type` for reasons why this might b
e
useful. Putting a descriptive string in as the type of the field for the
serializer is a useful idea if you're ever going to be using the serializer
output in some other place, outside of Django.
Converting field data for serialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. method:: Field.value_to_string(self, obj)
This method is used by the serializers to convert the field into a string for
output. Calling ``Field._get_val_from_obj(obj)`` is the best way to get the
value to serialize. For example, since our ``HandField`` uses strings for its
data storage anyway, we can reuse some existing conversion code::
class HandField(models.Field):
# ...
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_prep_value(value)
Some general advice
-------------------Writing a custom field can be a tricky process, particularly if you're doing
complex conversions between your Python types and your database and
serialization formats. Here are a couple of tips to make things go more
smoothly:
1. Look at the existing Django fields (in
:file:`django/db/models/fields/__init__.py`) for inspiration. Try to find
a field that's similar to what you want and extend it a little bit,
instead of creating an entirely new field from scratch.
2. Put a ``__str__()`` or ``__unicode__()`` method on the class you're
wrapping up as a field. There are a lot of places where the default
behavior of the field code is to call
:func:`~django.utils.encoding.force_text` on the value. (In our
examples in this document, ``value`` would be a ``Hand`` instance, not a
``HandField``). So if your ``__unicode__()`` method automatically
converts to the string form of your Python object, you can save yourself
a lot of work.
Writing a ``FileField`` subclass
=================================
In addition to the above methods, fields that deal with files have a few other
special requirements which must be taken into account. The majority of the
mechanics provided by ``FileField``, such as controlling database storage and
retrieval, can remain unchanged, leaving subclasses to deal with the challenge
of supporting a particular type of file.
Django provides a ``File`` class, which is used as
contents and operations. This can be subclassed to
accessed, and what methods are available. It lives
``django.db.models.fields.files``, and its default