Fixed #24295 -- Allowed ModelForm meta to specify form field classes.
Thanks Carl Meyer and Markus Holtermann for the reviews.
This commit is contained in:
parent
e8cf4f8abe
commit
00a889167f
|
@ -154,7 +154,8 @@ def model_to_dict(instance, fields=None, exclude=None):
|
||||||
|
|
||||||
def fields_for_model(model, fields=None, exclude=None, widgets=None,
|
def fields_for_model(model, fields=None, exclude=None, widgets=None,
|
||||||
formfield_callback=None, localized_fields=None,
|
formfield_callback=None, localized_fields=None,
|
||||||
labels=None, help_texts=None, error_messages=None):
|
labels=None, help_texts=None, error_messages=None,
|
||||||
|
field_classes=None):
|
||||||
"""
|
"""
|
||||||
Returns a ``OrderedDict`` containing form fields for the given model.
|
Returns a ``OrderedDict`` containing form fields for the given model.
|
||||||
|
|
||||||
|
@ -167,6 +168,9 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None,
|
||||||
|
|
||||||
``widgets`` is a dictionary of model field names mapped to a widget.
|
``widgets`` is a dictionary of model field names mapped to a widget.
|
||||||
|
|
||||||
|
``formfield_callback`` is a callable that takes a model field and returns
|
||||||
|
a form field.
|
||||||
|
|
||||||
``localized_fields`` is a list of names of fields which should be localized.
|
``localized_fields`` is a list of names of fields which should be localized.
|
||||||
|
|
||||||
``labels`` is a dictionary of model field names mapped to a label.
|
``labels`` is a dictionary of model field names mapped to a label.
|
||||||
|
@ -176,8 +180,8 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None,
|
||||||
``error_messages`` is a dictionary of model field names mapped to a
|
``error_messages`` is a dictionary of model field names mapped to a
|
||||||
dictionary of error messages.
|
dictionary of error messages.
|
||||||
|
|
||||||
``formfield_callback`` is a callable that takes a model field and returns
|
``field_classes`` is a dictionary of model field names mapped to a form
|
||||||
a form field.
|
field class.
|
||||||
"""
|
"""
|
||||||
field_list = []
|
field_list = []
|
||||||
ignored = []
|
ignored = []
|
||||||
|
@ -205,6 +209,8 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None,
|
||||||
kwargs['help_text'] = help_texts[f.name]
|
kwargs['help_text'] = help_texts[f.name]
|
||||||
if error_messages and f.name in error_messages:
|
if error_messages and f.name in error_messages:
|
||||||
kwargs['error_messages'] = error_messages[f.name]
|
kwargs['error_messages'] = error_messages[f.name]
|
||||||
|
if field_classes and f.name in field_classes:
|
||||||
|
kwargs['form_class'] = field_classes[f.name]
|
||||||
|
|
||||||
if formfield_callback is None:
|
if formfield_callback is None:
|
||||||
formfield = f.formfield(**kwargs)
|
formfield = f.formfield(**kwargs)
|
||||||
|
@ -236,6 +242,7 @@ class ModelFormOptions(object):
|
||||||
self.labels = getattr(options, 'labels', None)
|
self.labels = getattr(options, 'labels', None)
|
||||||
self.help_texts = getattr(options, 'help_texts', None)
|
self.help_texts = getattr(options, 'help_texts', None)
|
||||||
self.error_messages = getattr(options, 'error_messages', None)
|
self.error_messages = getattr(options, 'error_messages', None)
|
||||||
|
self.field_classes = getattr(options, 'field_classes', None)
|
||||||
|
|
||||||
|
|
||||||
class ModelFormMetaclass(DeclarativeFieldsMetaclass):
|
class ModelFormMetaclass(DeclarativeFieldsMetaclass):
|
||||||
|
@ -280,7 +287,8 @@ class ModelFormMetaclass(DeclarativeFieldsMetaclass):
|
||||||
fields = fields_for_model(opts.model, opts.fields, opts.exclude,
|
fields = fields_for_model(opts.model, opts.fields, opts.exclude,
|
||||||
opts.widgets, formfield_callback,
|
opts.widgets, formfield_callback,
|
||||||
opts.localized_fields, opts.labels,
|
opts.localized_fields, opts.labels,
|
||||||
opts.help_texts, opts.error_messages)
|
opts.help_texts, opts.error_messages,
|
||||||
|
opts.field_classes)
|
||||||
|
|
||||||
# make sure opts.fields doesn't specify an invalid field
|
# make sure opts.fields doesn't specify an invalid field
|
||||||
none_model_fields = [k for k, v in six.iteritems(fields) if not v]
|
none_model_fields = [k for k, v in six.iteritems(fields) if not v]
|
||||||
|
@ -469,7 +477,8 @@ class ModelForm(six.with_metaclass(ModelFormMetaclass, BaseModelForm)):
|
||||||
|
|
||||||
def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
|
def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
|
||||||
formfield_callback=None, widgets=None, localized_fields=None,
|
formfield_callback=None, widgets=None, localized_fields=None,
|
||||||
labels=None, help_texts=None, error_messages=None):
|
labels=None, help_texts=None, error_messages=None,
|
||||||
|
field_classes=None):
|
||||||
"""
|
"""
|
||||||
Returns a ModelForm containing form fields for the given model.
|
Returns a ModelForm containing form fields for the given model.
|
||||||
|
|
||||||
|
@ -494,6 +503,9 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
|
||||||
|
|
||||||
``error_messages`` is a dictionary of model field names mapped to a
|
``error_messages`` is a dictionary of model field names mapped to a
|
||||||
dictionary of error messages.
|
dictionary of error messages.
|
||||||
|
|
||||||
|
``field_classes`` is a dictionary of model field names mapped to a form
|
||||||
|
field class.
|
||||||
"""
|
"""
|
||||||
# Create the inner Meta class. FIXME: ideally, we should be able to
|
# Create the inner Meta class. FIXME: ideally, we should be able to
|
||||||
# construct a ModelForm without creating and passing in a temporary
|
# construct a ModelForm without creating and passing in a temporary
|
||||||
|
@ -515,6 +527,8 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None,
|
||||||
attrs['help_texts'] = help_texts
|
attrs['help_texts'] = help_texts
|
||||||
if error_messages is not None:
|
if error_messages is not None:
|
||||||
attrs['error_messages'] = error_messages
|
attrs['error_messages'] = error_messages
|
||||||
|
if field_classes is not None:
|
||||||
|
attrs['field_classes'] = field_classes
|
||||||
|
|
||||||
# If parent form class already has an inner Meta, the Meta we're
|
# If parent form class already has an inner Meta, the Meta we're
|
||||||
# creating needs to inherit from the parent's inner meta.
|
# creating needs to inherit from the parent's inner meta.
|
||||||
|
@ -813,7 +827,7 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None,
|
||||||
can_order=False, max_num=None, fields=None, exclude=None,
|
can_order=False, max_num=None, fields=None, exclude=None,
|
||||||
widgets=None, validate_max=False, localized_fields=None,
|
widgets=None, validate_max=False, localized_fields=None,
|
||||||
labels=None, help_texts=None, error_messages=None,
|
labels=None, help_texts=None, error_messages=None,
|
||||||
min_num=None, validate_min=False):
|
min_num=None, validate_min=False, field_classes=None):
|
||||||
"""
|
"""
|
||||||
Returns a FormSet class for the given Django model class.
|
Returns a FormSet class for the given Django model class.
|
||||||
"""
|
"""
|
||||||
|
@ -830,7 +844,8 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None,
|
||||||
form = modelform_factory(model, form=form, fields=fields, exclude=exclude,
|
form = modelform_factory(model, form=form, fields=fields, exclude=exclude,
|
||||||
formfield_callback=formfield_callback,
|
formfield_callback=formfield_callback,
|
||||||
widgets=widgets, localized_fields=localized_fields,
|
widgets=widgets, localized_fields=localized_fields,
|
||||||
labels=labels, help_texts=help_texts, error_messages=error_messages)
|
labels=labels, help_texts=help_texts,
|
||||||
|
error_messages=error_messages, field_classes=field_classes)
|
||||||
FormSet = formset_factory(form, formset, extra=extra, min_num=min_num, max_num=max_num,
|
FormSet = formset_factory(form, formset, extra=extra, min_num=min_num, max_num=max_num,
|
||||||
can_order=can_order, can_delete=can_delete,
|
can_order=can_order, can_delete=can_delete,
|
||||||
validate_min=validate_min, validate_max=validate_max)
|
validate_min=validate_min, validate_max=validate_max)
|
||||||
|
@ -991,7 +1006,7 @@ def inlineformset_factory(parent_model, model, form=ModelForm,
|
||||||
can_delete=True, max_num=None, formfield_callback=None,
|
can_delete=True, max_num=None, formfield_callback=None,
|
||||||
widgets=None, validate_max=False, localized_fields=None,
|
widgets=None, validate_max=False, localized_fields=None,
|
||||||
labels=None, help_texts=None, error_messages=None,
|
labels=None, help_texts=None, error_messages=None,
|
||||||
min_num=None, validate_min=False):
|
min_num=None, validate_min=False, field_classes=None):
|
||||||
"""
|
"""
|
||||||
Returns an ``InlineFormSet`` for the given kwargs.
|
Returns an ``InlineFormSet`` for the given kwargs.
|
||||||
|
|
||||||
|
@ -1020,6 +1035,7 @@ def inlineformset_factory(parent_model, model, form=ModelForm,
|
||||||
'labels': labels,
|
'labels': labels,
|
||||||
'help_texts': help_texts,
|
'help_texts': help_texts,
|
||||||
'error_messages': error_messages,
|
'error_messages': error_messages,
|
||||||
|
'field_classes': field_classes,
|
||||||
}
|
}
|
||||||
FormSet = modelformset_factory(model, **kwargs)
|
FormSet = modelformset_factory(model, **kwargs)
|
||||||
FormSet.fk = fk
|
FormSet.fk = fk
|
||||||
|
|
|
@ -8,7 +8,7 @@ Model Form API reference. For introductory material about model forms, see the
|
||||||
.. module:: django.forms.models
|
.. module:: django.forms.models
|
||||||
:synopsis: Django's functions for building model forms and formsets.
|
:synopsis: Django's functions for building model forms and formsets.
|
||||||
|
|
||||||
.. function:: modelform_factory(model, form=ModelForm, fields=None, exclude=None, formfield_callback=None, widgets=None, localized_fields=None, labels=None, help_texts=None, error_messages=None)
|
.. function:: modelform_factory(model, form=ModelForm, fields=None, exclude=None, formfield_callback=None, widgets=None, localized_fields=None, labels=None, help_texts=None, error_messages=None, field_classes=None)
|
||||||
|
|
||||||
Returns a :class:`~django.forms.ModelForm` class for the given ``model``.
|
Returns a :class:`~django.forms.ModelForm` class for the given ``model``.
|
||||||
You can optionally pass a ``form`` argument to use as a starting point for
|
You can optionally pass a ``form`` argument to use as a starting point for
|
||||||
|
@ -21,11 +21,11 @@ Model Form API reference. For introductory material about model forms, see the
|
||||||
fields will be excluded from the returned fields, even if they are listed
|
fields will be excluded from the returned fields, even if they are listed
|
||||||
in the ``fields`` argument.
|
in the ``fields`` argument.
|
||||||
|
|
||||||
``widgets`` is a dictionary of model field names mapped to a widget.
|
|
||||||
|
|
||||||
``formfield_callback`` is a callable that takes a model field and returns
|
``formfield_callback`` is a callable that takes a model field and returns
|
||||||
a form field.
|
a form field.
|
||||||
|
|
||||||
|
``widgets`` is a dictionary of model field names mapped to a widget.
|
||||||
|
|
||||||
``localized_fields`` is a list of names of fields which should be localized.
|
``localized_fields`` is a list of names of fields which should be localized.
|
||||||
|
|
||||||
``labels`` is a dictionary of model field names mapped to a label.
|
``labels`` is a dictionary of model field names mapped to a label.
|
||||||
|
@ -35,6 +35,9 @@ Model Form API reference. For introductory material about model forms, see the
|
||||||
``error_messages`` is a dictionary of model field names mapped to a
|
``error_messages`` is a dictionary of model field names mapped to a
|
||||||
dictionary of error messages.
|
dictionary of error messages.
|
||||||
|
|
||||||
|
``field_classes`` is a dictionary of model field names mapped to a form
|
||||||
|
field class.
|
||||||
|
|
||||||
See :ref:`modelforms-factory` for example usage.
|
See :ref:`modelforms-factory` for example usage.
|
||||||
|
|
||||||
You must provide the list of fields explicitly, either via keyword arguments
|
You must provide the list of fields explicitly, either via keyword arguments
|
||||||
|
@ -48,14 +51,18 @@ Model Form API reference. For introductory material about model forms, see the
|
||||||
Previously, omitting the list of fields was allowed and resulted in
|
Previously, omitting the list of fields was allowed and resulted in
|
||||||
a form with all fields of the model.
|
a form with all fields of the model.
|
||||||
|
|
||||||
.. function:: modelformset_factory(model, form=ModelForm, formfield_callback=None, formset=BaseModelFormSet, extra=1, can_delete=False, can_order=False, max_num=None, fields=None, exclude=None, widgets=None, validate_max=False, localized_fields=None, labels=None, help_texts=None, error_messages=None, min_num=None, validate_min=False)
|
.. versionadded:: 1.9
|
||||||
|
|
||||||
|
The ``field_classes`` keyword argument was added.
|
||||||
|
|
||||||
|
.. function:: modelformset_factory(model, form=ModelForm, formfield_callback=None, formset=BaseModelFormSet, extra=1, can_delete=False, can_order=False, max_num=None, fields=None, exclude=None, widgets=None, validate_max=False, localized_fields=None, labels=None, help_texts=None, error_messages=None, min_num=None, validate_min=False, field_classes=None)
|
||||||
|
|
||||||
Returns a ``FormSet`` class for the given ``model`` class.
|
Returns a ``FormSet`` class for the given ``model`` class.
|
||||||
|
|
||||||
Arguments ``model``, ``form``, ``fields``, ``exclude``,
|
Arguments ``model``, ``form``, ``fields``, ``exclude``,
|
||||||
``formfield_callback``, ``widgets``, ``localized_fields``, ``labels``,
|
``formfield_callback``, ``widgets``, ``localized_fields``, ``labels``,
|
||||||
``help_texts``, and ``error_messages`` are all passed through to
|
``help_texts``, ``error_messages``, and ``field_classes`` are all passed
|
||||||
:func:`~django.forms.models.modelform_factory`.
|
through to :func:`~django.forms.models.modelform_factory`.
|
||||||
|
|
||||||
Arguments ``formset``, ``extra``, ``max_num``, ``can_order``,
|
Arguments ``formset``, ``extra``, ``max_num``, ``can_order``,
|
||||||
``can_delete`` and ``validate_max`` are passed through to
|
``can_delete`` and ``validate_max`` are passed through to
|
||||||
|
@ -64,7 +71,11 @@ Model Form API reference. For introductory material about model forms, see the
|
||||||
|
|
||||||
See :ref:`model-formsets` for example usage.
|
See :ref:`model-formsets` for example usage.
|
||||||
|
|
||||||
.. function:: inlineformset_factory(parent_model, model, form=ModelForm, formset=BaseInlineFormSet, fk_name=None, fields=None, exclude=None, extra=3, can_order=False, can_delete=True, max_num=None, formfield_callback=None, widgets=None, validate_max=False, localized_fields=None, labels=None, help_texts=None, error_messages=None, min_num=None, validate_min=False)
|
.. versionadded:: 1.9
|
||||||
|
|
||||||
|
The ``field_classes`` keyword argument was added.
|
||||||
|
|
||||||
|
.. function:: inlineformset_factory(parent_model, model, form=ModelForm, formset=BaseInlineFormSet, fk_name=None, fields=None, exclude=None, extra=3, can_order=False, can_delete=True, max_num=None, formfield_callback=None, widgets=None, validate_max=False, localized_fields=None, labels=None, help_texts=None, error_messages=None, min_num=None, validate_min=False, field_classes=None)
|
||||||
|
|
||||||
Returns an ``InlineFormSet`` using :func:`modelformset_factory` with
|
Returns an ``InlineFormSet`` using :func:`modelformset_factory` with
|
||||||
defaults of ``formset=``:class:`~django.forms.models.BaseInlineFormSet`,
|
defaults of ``formset=``:class:`~django.forms.models.BaseInlineFormSet`,
|
||||||
|
@ -74,3 +85,7 @@ Model Form API reference. For introductory material about model forms, see the
|
||||||
the ``parent_model``, you must specify a ``fk_name``.
|
the ``parent_model``, you must specify a ``fk_name``.
|
||||||
|
|
||||||
See :ref:`inline-formsets` for example usage.
|
See :ref:`inline-formsets` for example usage.
|
||||||
|
|
||||||
|
.. versionadded:: 1.9
|
||||||
|
|
||||||
|
The ``field_classes`` keyword argument was added.
|
||||||
|
|
|
@ -106,7 +106,9 @@ File Uploads
|
||||||
Forms
|
Forms
|
||||||
^^^^^
|
^^^^^
|
||||||
|
|
||||||
* ...
|
* :class:`~django.forms.ModelForm` accepts the new ``Meta`` option
|
||||||
|
``field_classes`` to customize the type of the fields. See
|
||||||
|
:ref:`modelforms-overriding-default-fields` for details.
|
||||||
|
|
||||||
Generic Views
|
Generic Views
|
||||||
^^^^^^^^^^^^^
|
^^^^^^^^^^^^^
|
||||||
|
|
|
@ -475,9 +475,8 @@ Overriding the default fields
|
||||||
|
|
||||||
The default field types, as described in the `Field types`_ table above, are
|
The default field types, as described in the `Field types`_ table above, are
|
||||||
sensible defaults. If you have a ``DateField`` in your model, chances are you'd
|
sensible defaults. If you have a ``DateField`` in your model, chances are you'd
|
||||||
want that to be represented as a ``DateField`` in your form. But
|
want that to be represented as a ``DateField`` in your form. But ``ModelForm``
|
||||||
``ModelForm`` gives you the flexibility of changing the form field type and
|
gives you the flexibility of changing the form field for a given model.
|
||||||
widget for a given model field.
|
|
||||||
|
|
||||||
To specify a custom widget for a field, use the ``widgets`` attribute of the
|
To specify a custom widget for a field, use the ``widgets`` attribute of the
|
||||||
inner ``Meta`` class. This should be a dictionary mapping field names to widget
|
inner ``Meta`` class. This should be a dictionary mapping field names to widget
|
||||||
|
@ -525,9 +524,8 @@ the ``name`` field::
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
Finally, if you want complete control over of a field -- including its type,
|
You can also specify ``field_classes`` to customize the type of fields
|
||||||
validators, etc. -- you can do this by declaratively specifying fields like you
|
instantiated by the form.
|
||||||
would in a regular ``Form``.
|
|
||||||
|
|
||||||
For example, if you wanted to use ``MySlugFormField`` for the ``slug``
|
For example, if you wanted to use ``MySlugFormField`` for the ``slug``
|
||||||
field, you could do the following::
|
field, you could do the following::
|
||||||
|
@ -536,13 +534,18 @@ field, you could do the following::
|
||||||
from myapp.models import Article
|
from myapp.models import Article
|
||||||
|
|
||||||
class ArticleForm(ModelForm):
|
class ArticleForm(ModelForm):
|
||||||
slug = MySlugFormField()
|
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Article
|
model = Article
|
||||||
fields = ['pub_date', 'headline', 'content', 'reporter', 'slug']
|
fields = ['pub_date', 'headline', 'content', 'reporter', 'slug']
|
||||||
|
field_classes = {
|
||||||
|
'slug': MySlugFormField,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Finally, if you want complete control over of a field -- including its type,
|
||||||
|
validators, required, etc. -- you can do this by declaratively specifying
|
||||||
|
fields like you would in a regular ``Form``.
|
||||||
|
|
||||||
If you want to specify a field's validators, you can do so by defining
|
If you want to specify a field's validators, you can do so by defining
|
||||||
the field declaratively and setting its ``validators`` parameter::
|
the field declaratively and setting its ``validators`` parameter::
|
||||||
|
|
||||||
|
@ -556,6 +559,10 @@ the field declaratively and setting its ``validators`` parameter::
|
||||||
model = Article
|
model = Article
|
||||||
fields = ['pub_date', 'headline', 'content', 'reporter', 'slug']
|
fields = ['pub_date', 'headline', 'content', 'reporter', 'slug']
|
||||||
|
|
||||||
|
.. versionadded:: 1.9
|
||||||
|
|
||||||
|
The ``Meta.field_classes`` attribute was added.
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
When you explicitly instantiate a form field like this, it is important to
|
When you explicitly instantiate a form field like this, it is important to
|
||||||
|
|
|
@ -11,7 +11,7 @@ from django.core.exceptions import (
|
||||||
)
|
)
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.core.validators import ValidationError
|
from django.core.validators import ValidationError
|
||||||
from django.db import connection
|
from django.db import connection, models
|
||||||
from django.db.models.query import EmptyQuerySet
|
from django.db.models.query import EmptyQuerySet
|
||||||
from django.forms.models import (
|
from django.forms.models import (
|
||||||
ModelFormMetaclass, construct_instance, fields_for_model, model_to_dict,
|
ModelFormMetaclass, construct_instance, fields_for_model, model_to_dict,
|
||||||
|
@ -545,6 +545,9 @@ class FieldOverridesByFormMetaForm(forms.ModelForm):
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
field_classes = {
|
||||||
|
'url': forms.URLField,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class TestFieldOverridesByFormMeta(TestCase):
|
class TestFieldOverridesByFormMeta(TestCase):
|
||||||
|
@ -588,7 +591,7 @@ class TestFieldOverridesByFormMeta(TestCase):
|
||||||
def test_error_messages_overrides(self):
|
def test_error_messages_overrides(self):
|
||||||
form = FieldOverridesByFormMetaForm(data={
|
form = FieldOverridesByFormMetaForm(data={
|
||||||
'name': 'Category',
|
'name': 'Category',
|
||||||
'url': '/category/',
|
'url': 'http://www.example.com/category/',
|
||||||
'slug': '!%#*@',
|
'slug': '!%#*@',
|
||||||
})
|
})
|
||||||
form.full_clean()
|
form.full_clean()
|
||||||
|
@ -599,6 +602,11 @@ class TestFieldOverridesByFormMeta(TestCase):
|
||||||
]
|
]
|
||||||
self.assertEqual(form.errors, {'slug': error})
|
self.assertEqual(form.errors, {'slug': error})
|
||||||
|
|
||||||
|
def test_field_type_overrides(self):
|
||||||
|
form = FieldOverridesByFormMetaForm()
|
||||||
|
self.assertIs(Category._meta.get_field('url').__class__, models.CharField)
|
||||||
|
self.assertIsInstance(form.fields['url'], forms.URLField)
|
||||||
|
|
||||||
|
|
||||||
class IncompleteCategoryFormWithFields(forms.ModelForm):
|
class IncompleteCategoryFormWithFields(forms.ModelForm):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1431,3 +1431,21 @@ class TestModelFormsetOverridesTroughFormMeta(TestCase):
|
||||||
form = BookFormSet.form(data={'title': 'Foo ' * 30, 'author': author.id})
|
form = BookFormSet.form(data={'title': 'Foo ' * 30, 'author': author.id})
|
||||||
form.full_clean()
|
form.full_clean()
|
||||||
self.assertEqual(form.errors, {'title': ['Title too long!!']})
|
self.assertEqual(form.errors, {'title': ['Title too long!!']})
|
||||||
|
|
||||||
|
def test_modelformset_factory_field_class_overrides(self):
|
||||||
|
author = Author.objects.create(pk=1, name='Charles Baudelaire')
|
||||||
|
BookFormSet = modelformset_factory(Book, fields="__all__", field_classes={
|
||||||
|
'title': forms.SlugField,
|
||||||
|
})
|
||||||
|
form = BookFormSet.form(data={'title': 'Foo ' * 30, 'author': author.id})
|
||||||
|
self.assertIs(Book._meta.get_field('title').__class__, models.CharField)
|
||||||
|
self.assertIsInstance(form.fields['title'], forms.SlugField)
|
||||||
|
|
||||||
|
def test_inlineformset_factory_field_class_overrides(self):
|
||||||
|
author = Author.objects.create(pk=1, name='Charles Baudelaire')
|
||||||
|
BookFormSet = inlineformset_factory(Author, Book, fields="__all__", field_classes={
|
||||||
|
'title': forms.SlugField,
|
||||||
|
})
|
||||||
|
form = BookFormSet.form(data={'title': 'Foo ' * 30, 'author': author.id})
|
||||||
|
self.assertIs(Book._meta.get_field('title').__class__, models.CharField)
|
||||||
|
self.assertIsInstance(form.fields['title'], forms.SlugField)
|
||||||
|
|
Loading…
Reference in New Issue