Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed #22959, #23473 #3271

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions docs/ref/validators.txt
Expand Up @@ -37,6 +37,12 @@ use the same validator with forms::
class MyForm(forms.Form):
even_field = forms.IntegerField(validators=[validate_even])

You can also use a class with a ``__call__`` method for configurable or more
complex validators, similar to the :class:`RegexValidator`. If the validator is
passed to a model field you should make sure it is :ref:`serializable by the
migration framework <migration-serializing>` and therefore has a
:ref:`deconstruct() <custom-deconstruct-method>` and ``__eq__()`` method.

How validators are run
======================

Expand Down
9 changes: 9 additions & 0 deletions docs/topics/migrations.txt
Expand Up @@ -601,6 +601,10 @@ of three things ``(path, args, kwargs)``:
Django will write out the value as an instantiation of your class with the
given arguments, similar to the way it writes out references to Django fields.

To prevent infinite migration creation you should also add a ``__eq__()``
method to the decorated class. This function will be called by Django's
migration framework to detect changes between states.

As long as all of the arguments to your class' constructor are themselves
serializable, you can just use the ``@deconstructible`` class decorator
from ``django.utils.deconstruct`` to add the method::
Expand All @@ -611,8 +615,13 @@ from ``django.utils.deconstruct`` to add the method::
class MyCustomClass(object):

def __init__(self, foo=1):
self.foo = foo
...

def __eq__(self, other):
return self.foo == other.foo


The decorator adds logic to capture and preserve the arguments on their
way into your constructor, and then returns those arguments exactly when
deconstruct() is called.
Expand Down