summaryrefslogtreecommitdiff
path: root/docs/custom_model_fields.txt
diff options
context:
space:
mode:
Diffstat (limited to 'docs/custom_model_fields.txt')
-rw-r--r--docs/custom_model_fields.txt59
1 files changed, 38 insertions, 21 deletions
diff --git a/docs/custom_model_fields.txt b/docs/custom_model_fields.txt
index cbaac873e3..6b8f3c3ac6 100644
--- a/docs/custom_model_fields.txt
+++ b/docs/custom_model_fields.txt
@@ -111,7 +111,7 @@ into the precise details of what ``Field`` can do later on; for now, suffice it
to say that everything descends from ``Field`` and then customizes key pieces
of the class behavior.
-.. _form fields: ../newforms/#fields
+.. _form fields: ../forms/#fields
It's important to realize that a Django field class is not what is stored in
your model attributes. The model attributes contain normal Python objects. The
@@ -385,8 +385,8 @@ Python object type we want to store in the model's attribute.
called when it is created, you should be using `The SubfieldBase metaclass`_
mentioned earlier. Otherwise ``to_python()`` won't be called automatically.
-``get_db_prep_save(self, value)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+``get_db_prep_value(self, value)``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This is the reverse of ``to_python()`` when working with the database backends
(as opposed to serialization). The ``value`` parameter is the current value of
@@ -399,10 +399,20 @@ For example::
class HandField(models.Field):
# ...
- def get_db_prep_save(self, value):
+ def get_db_prep_value(self, value):
return ''.join([''.join(l) for l in (value.north,
value.east, value.south, value.west)])
+``get_db_prep_save(self, value)``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Same as the above, but called when the Field value must be *saved* to the
+database. As the default implementation just calls ``get_db_prep_value``, you
+shouldn't need to implement this method unless your custom field need a special
+conversion when being saved that is not the same as the used for normal query
+parameters (which is implemented by ``get_db_prep_value``).
+
+
``pre_save(self, model_instance, add)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -440,14 +450,21 @@ by with handling the lookup types that need special handling for your field
and pass the rest of the ``get_db_prep_lookup()`` method of the parent class.
If you needed to implement ``get_db_prep_save()``, you will usually need to
-implement ``get_db_prep_lookup()``. The usual reason is because of the
-``range`` and ``in`` lookups. In these case, you will passed a list of
-objects (presumably of the right type) and will need to convert them to a list
-of things of the right type for passing to the database. Sometimes you can
-reuse ``get_db_prep_save()``, or at least factor out some common pieces from
-both methods into a help function.
+implement ``get_db_prep_lookup()``. If you don't, ``get_db_prep_value`` will be
+called by the default implementation, to manage ``exact``, ``gt``, ``gte``,
+``lt``, ``lte``, ``in`` and ``range`` lookups.
-For example::
+You may also want to implement this method to limit the lookup types that could
+be used with your custom field type.
+
+Note that, for ``range`` and ``in`` lookups, ``get_db_prep_lookup`` will receive
+a list of objects (presumably of the right type) and will need to convert them
+to a list of things of the right type for passing to the database. Most of the
+time, you can reuse ``get_db_prep_value()``, or at least factor out some common
+pieces.
+
+For example, the following code implements ``get_db_prep_lookup`` to limit the
+accepted lookup types to ``exact`` and ``in``::
class HandField(models.Field):
# ...
@@ -455,9 +472,9 @@ For example::
def get_db_prep_lookup(self, lookup_type, value):
# We only handle 'exact' and 'in'. All others are errors.
if lookup_type == 'exact':
- return self.get_db_prep_save(value)
+ return self.get_db_prep_value(value)
elif lookup_type == 'in':
- return [self.get_db_prep_save(v) for v in value]
+ return [self.get_db_prep_value(v) for v in value]
else:
raise TypeError('Lookup type %r not supported.' % lookup_type)
@@ -493,8 +510,8 @@ This assumes we're imported a ``MyFormField`` field class (which has its own
default widget). This document doesn't cover the details of writing custom form
fields.
-.. _helper functions: ../newforms/#generating-forms-for-models
-.. _forms documentation: ../newforms/
+.. _helper functions: ../forms/#generating-forms-for-models
+.. _forms documentation: ../forms/
``get_internal_type(self)``
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -538,11 +555,11 @@ serializer output in some other place, outside of Django.
Although implementing this method is necessary to allow field
serialization, the API might change in the future.
-Returns a dictionary, mapping the field's attribute name to a flattened string
-version of the data. This method has some internal uses that aren't of
-interest to use here (mostly having to do with manipulators). For our
-purposes, it's sufficient to return a one item dictionary that maps the
-attribute name to a string.
+Returns a dictionary, mapping the field's attribute name to a
+flattened string version of the data. This method has some internal
+uses that aren't of interest to use here (mostly having to do with
+forms). For our purposes, it's sufficient to return a one item
+dictionary that maps the attribute name to a string.
This method is used by the serializers to convert the field into a string for
output. You can ignore the input parameters for serialization purposes,
@@ -557,7 +574,7 @@ we can reuse some existing conversion code::
def flatten_data(self, follow, obj=None):
value = self._get_val_from_obj(obj)
- return {self.attname: self.get_db_prep_save(value)}
+ return {self.attname: self.get_db_prep_value(value)}
Some general advice
--------------------