[1.7.x] Fixed #22497 -- Highlighted difference between field and class deconstruction.
Thanks nliberg for the suggestion.
Backport of b829d53b37
from master
This commit is contained in:
parent
23f3c53aff
commit
63ae243a13
|
@ -230,6 +230,8 @@ 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
|
meaning they do for normal Django fields. See the :doc:`field documentation
|
||||||
</ref/models/fields>` for examples and details.
|
</ref/models/fields>` for examples and details.
|
||||||
|
|
||||||
|
.. _custom-field-deconstruct-method:
|
||||||
|
|
||||||
Field deconstruction
|
Field deconstruction
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
@ -239,19 +241,21 @@ Field deconstruction
|
||||||
above. If you have custom fields from previous versions they will
|
above. If you have custom fields from previous versions they will
|
||||||
need this method added before you can use them with migrations.
|
need this method added before you can use them with migrations.
|
||||||
|
|
||||||
The counterpoint to writing your ``__init__`` method is writing the
|
The counterpoint to writing your ``__init__()`` method is writing the
|
||||||
``deconstruct`` method. This method tells Django how to take an instance
|
``deconstruct()`` method. This method tells Django how to take an instance
|
||||||
of your new field and reduce it to a serialized form - in particular, what
|
of your new field and reduce it to a serialized form - in particular, what
|
||||||
arguments to pass to ``__init__`` to re-create it.
|
arguments to pass to ``__init__()`` to re-create it.
|
||||||
|
|
||||||
If you haven't added any extra options on top of the field you inherited from,
|
If you haven't added any extra options on top of the field you inherited from,
|
||||||
then there's no need to write a new ``deconstruct`` method. If, however, you're
|
then there's no need to write a new ``deconstruct()`` method. If, however,
|
||||||
changing the arguments passed in ``__init__`` (like we are in ``HandField``),
|
you're, changing the arguments passed in ``__init__()`` (like we are in
|
||||||
you'll need to supplement the values being passed.
|
``HandField``), you'll need to supplement the values being passed.
|
||||||
|
|
||||||
The contract of ``deconstruct`` is simple; it returns a tuple of four items:
|
The contract of ``deconstruct()`` is simple; it returns a tuple of four items:
|
||||||
the field's attribute name, the full import path of the field class, the
|
the field's attribute name, the full import path of the field class, the
|
||||||
positional arguments (as a list), and the keyword arguments (as a dict).
|
positional arguments (as a list), and the keyword arguments (as a dict). Note
|
||||||
|
this is different from the ``deconstruct()`` method :ref:`for custom classes
|
||||||
|
<custom-deconstruct-method>` which returns a tuple of three things.
|
||||||
|
|
||||||
As a custom field author, you don't need to care about the first two values;
|
As a custom field author, you don't need to care about the first two values;
|
||||||
the base ``Field`` class has all the code to work out the field's attribute
|
the base ``Field`` class has all the code to work out the field's attribute
|
||||||
|
@ -259,7 +263,7 @@ name and import path. You do, however, have to care about the positional
|
||||||
and keyword arguments, as these are likely the things you are changing.
|
and keyword arguments, as these are likely the things you are changing.
|
||||||
|
|
||||||
For example, in our ``HandField`` class we're always forcibly setting
|
For example, in our ``HandField`` class we're always forcibly setting
|
||||||
max_length in ``__init__``. The ``deconstruct`` method on the base ``Field``
|
max_length in ``__init__()``. The ``deconstruct()`` method on the base ``Field``
|
||||||
class will see this and try to return it in the keyword arguments; thus,
|
class will see this and try to return it in the keyword arguments; thus,
|
||||||
we can drop it from the keyword arguments for readability::
|
we can drop it from the keyword arguments for readability::
|
||||||
|
|
||||||
|
@ -296,7 +300,7 @@ into ``kwargs`` yourself::
|
||||||
return name, path, args, kwargs
|
return name, path, args, kwargs
|
||||||
|
|
||||||
More complex examples are beyond the scope of this document, but remember -
|
More complex examples are beyond the scope of this document, but remember -
|
||||||
for any configuration of your Field instance, ``deconstruct`` must return
|
for any configuration of your Field instance, ``deconstruct()`` must return
|
||||||
arguments that you can pass to ``__init__`` to reconstruct that state.
|
arguments that you can pass to ``__init__`` to reconstruct that state.
|
||||||
|
|
||||||
Pay extra attention if you set new default values for arguments in the
|
Pay extra attention if you set new default values for arguments in the
|
||||||
|
@ -460,7 +464,7 @@ For example::
|
||||||
|
|
||||||
The :meth:`.db_type` method is called by Django when the framework
|
The :meth:`.db_type` method is called by Django when the framework
|
||||||
constructs the ``CREATE TABLE`` statements for your application -- that is,
|
constructs the ``CREATE TABLE`` statements for your application -- that is,
|
||||||
when you first create your tables. It is also called when constructing a
|
when you first create your tables. It is also called when constructing a
|
||||||
``WHERE`` clause that includes the model field -- that is, when you retrieve data
|
``WHERE`` clause that includes the model field -- that is, when you retrieve data
|
||||||
using QuerySet methods like ``get()``, ``filter()``, and ``exclude()`` and have
|
using QuerySet methods like ``get()``, ``filter()``, and ``exclude()`` and have
|
||||||
the model field as an argument. It's not called at any other time, so it can afford to
|
the model field as an argument. It's not called at any other time, so it can afford to
|
||||||
|
|
|
@ -502,8 +502,10 @@ Adding a deconstruct() method
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
You can let Django serialize your own custom class instances by giving the class
|
You can let Django serialize your own custom class instances by giving the class
|
||||||
a ``deconstruct`` method. It takes no arguments, and should return a tuple
|
a ``deconstruct()`` method. It takes no arguments, and should return a tuple
|
||||||
of 3 things: ``(path, args, kwargs)``.
|
of three things: ``(path, args, kwargs)``. Note this return value is different
|
||||||
|
from the ``deconstruct()`` method :ref:`for custom fields
|
||||||
|
<custom-field-deconstruct-method>` which returns a tuple of four items.
|
||||||
|
|
||||||
``path`` should be the Python path to the class, with the class name included as the
|
``path`` should be the Python path to the class, with the class name included as the
|
||||||
last part (for example, ``myapp.custom_things.MyClass``). If your class is not
|
last part (for example, ``myapp.custom_things.MyClass``). If your class is not
|
||||||
|
|
Loading…
Reference in New Issue