Loading django/forms/models.py +24 −8 Original line number Diff line number Diff line Loading @@ -154,7 +154,8 @@ def model_to_dict(instance, fields=None, exclude=None): def fields_for_model(model, fields=None, exclude=None, widgets=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. Loading @@ -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. ``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. ``labels`` is a dictionary of model field names mapped to a label. Loading @@ -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 dictionary of error messages. ``formfield_callback`` is a callable that takes a model field and returns a form field. ``field_classes`` is a dictionary of model field names mapped to a form field class. """ field_list = [] ignored = [] Loading Loading @@ -205,6 +209,8 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None, kwargs['help_text'] = help_texts[f.name] if error_messages and f.name in error_messages: 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: formfield = f.formfield(**kwargs) Loading Loading @@ -236,6 +242,7 @@ class ModelFormOptions(object): self.labels = getattr(options, 'labels', None) self.help_texts = getattr(options, 'help_texts', None) self.error_messages = getattr(options, 'error_messages', None) self.field_classes = getattr(options, 'field_classes', None) class ModelFormMetaclass(DeclarativeFieldsMetaclass): Loading Loading @@ -280,7 +287,8 @@ class ModelFormMetaclass(DeclarativeFieldsMetaclass): fields = fields_for_model(opts.model, opts.fields, opts.exclude, opts.widgets, formfield_callback, 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 none_model_fields = [k for k, v in six.iteritems(fields) if not v] Loading Loading @@ -469,7 +477,8 @@ class ModelForm(six.with_metaclass(ModelFormMetaclass, BaseModelForm)): def 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): labels=None, help_texts=None, error_messages=None, field_classes=None): """ Returns a ModelForm containing form fields for the given model. Loading @@ -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 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 # construct a ModelForm without creating and passing in a temporary Loading @@ -515,6 +527,8 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None, attrs['help_texts'] = help_texts if error_messages is not None: 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 # creating needs to inherit from the parent's inner meta. Loading Loading @@ -813,7 +827,7 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None, 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): min_num=None, validate_min=False, field_classes=None): """ Returns a FormSet class for the given Django model class. """ Loading @@ -830,7 +844,8 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None, form = modelform_factory(model, form=form, fields=fields, exclude=exclude, formfield_callback=formfield_callback, 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, can_order=can_order, can_delete=can_delete, validate_min=validate_min, validate_max=validate_max) Loading Loading @@ -991,7 +1006,7 @@ def inlineformset_factory(parent_model, model, form=ModelForm, 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): min_num=None, validate_min=False, field_classes=None): """ Returns an ``InlineFormSet`` for the given kwargs. Loading Loading @@ -1020,6 +1035,7 @@ def inlineformset_factory(parent_model, model, form=ModelForm, 'labels': labels, 'help_texts': help_texts, 'error_messages': error_messages, 'field_classes': field_classes, } FormSet = modelformset_factory(model, **kwargs) FormSet.fk = fk Loading docs/ref/forms/models.txt +22 −7 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ Model Form API reference. For introductory material about model forms, see the .. module:: django.forms.models :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``. You can optionally pass a ``form`` argument to use as a starting point for Loading @@ -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 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 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. ``labels`` is a dictionary of model field names mapped to a label. Loading @@ -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 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. You must provide the list of fields explicitly, either via keyword arguments Loading @@ -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 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. Arguments ``model``, ``form``, ``fields``, ``exclude``, ``formfield_callback``, ``widgets``, ``localized_fields``, ``labels``, ``help_texts``, and ``error_messages`` are all passed through to :func:`~django.forms.models.modelform_factory`. ``help_texts``, ``error_messages``, and ``field_classes`` are all passed through to :func:`~django.forms.models.modelform_factory`. Arguments ``formset``, ``extra``, ``max_num``, ``can_order``, ``can_delete`` and ``validate_max`` are passed through to Loading @@ -64,7 +71,11 @@ Model Form API reference. For introductory material about model forms, see the 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 defaults of ``formset=``:class:`~django.forms.models.BaseInlineFormSet`, Loading @@ -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``. See :ref:`inline-formsets` for example usage. .. versionadded:: 1.9 The ``field_classes`` keyword argument was added. docs/releases/1.9.txt +3 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,9 @@ File Uploads 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 ^^^^^^^^^^^^^ Loading docs/topics/forms/modelforms.txt +15 −8 Original line number Diff line number Diff line Loading @@ -475,9 +475,8 @@ Overriding the default fields 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 want that to be represented as a ``DateField`` in your form. But ``ModelForm`` gives you the flexibility of changing the form field type and widget for a given model field. want that to be represented as a ``DateField`` in your form. But ``ModelForm`` gives you the flexibility of changing the form field for a given model. 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 Loading Loading @@ -525,9 +524,8 @@ the ``name`` field:: }, } Finally, if you want complete control over of a field -- including its type, validators, etc. -- you can do this by declaratively specifying fields like you would in a regular ``Form``. You can also specify ``field_classes`` to customize the type of fields instantiated by the form. For example, if you wanted to use ``MySlugFormField`` for the ``slug`` field, you could do the following:: Loading @@ -536,13 +534,18 @@ field, you could do the following:: from myapp.models import Article class ArticleForm(ModelForm): slug = MySlugFormField() class Meta: model = Article 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 the field declaratively and setting its ``validators`` parameter:: Loading @@ -556,6 +559,10 @@ the field declaratively and setting its ``validators`` parameter:: model = Article fields = ['pub_date', 'headline', 'content', 'reporter', 'slug'] .. versionadded:: 1.9 The ``Meta.field_classes`` attribute was added. .. note:: When you explicitly instantiate a form field like this, it is important to Loading tests/model_forms/tests.py +10 −2 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ from django.core.exceptions import ( ) from django.core.files.uploadedfile import SimpleUploadedFile 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.forms.models import ( ModelFormMetaclass, construct_instance, fields_for_model, model_to_dict, Loading Loading @@ -545,6 +545,9 @@ class FieldOverridesByFormMetaForm(forms.ModelForm): ) } } field_classes = { 'url': forms.URLField, } class TestFieldOverridesByFormMeta(TestCase): Loading Loading @@ -588,7 +591,7 @@ class TestFieldOverridesByFormMeta(TestCase): def test_error_messages_overrides(self): form = FieldOverridesByFormMetaForm(data={ 'name': 'Category', 'url': '/category/', 'url': 'http://www.example.com/category/', 'slug': '!%#*@', }) form.full_clean() Loading @@ -599,6 +602,11 @@ class TestFieldOverridesByFormMeta(TestCase): ] 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): """ Loading Loading
django/forms/models.py +24 −8 Original line number Diff line number Diff line Loading @@ -154,7 +154,8 @@ def model_to_dict(instance, fields=None, exclude=None): def fields_for_model(model, fields=None, exclude=None, widgets=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. Loading @@ -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. ``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. ``labels`` is a dictionary of model field names mapped to a label. Loading @@ -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 dictionary of error messages. ``formfield_callback`` is a callable that takes a model field and returns a form field. ``field_classes`` is a dictionary of model field names mapped to a form field class. """ field_list = [] ignored = [] Loading Loading @@ -205,6 +209,8 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None, kwargs['help_text'] = help_texts[f.name] if error_messages and f.name in error_messages: 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: formfield = f.formfield(**kwargs) Loading Loading @@ -236,6 +242,7 @@ class ModelFormOptions(object): self.labels = getattr(options, 'labels', None) self.help_texts = getattr(options, 'help_texts', None) self.error_messages = getattr(options, 'error_messages', None) self.field_classes = getattr(options, 'field_classes', None) class ModelFormMetaclass(DeclarativeFieldsMetaclass): Loading Loading @@ -280,7 +287,8 @@ class ModelFormMetaclass(DeclarativeFieldsMetaclass): fields = fields_for_model(opts.model, opts.fields, opts.exclude, opts.widgets, formfield_callback, 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 none_model_fields = [k for k, v in six.iteritems(fields) if not v] Loading Loading @@ -469,7 +477,8 @@ class ModelForm(six.with_metaclass(ModelFormMetaclass, BaseModelForm)): def 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): labels=None, help_texts=None, error_messages=None, field_classes=None): """ Returns a ModelForm containing form fields for the given model. Loading @@ -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 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 # construct a ModelForm without creating and passing in a temporary Loading @@ -515,6 +527,8 @@ def modelform_factory(model, form=ModelForm, fields=None, exclude=None, attrs['help_texts'] = help_texts if error_messages is not None: 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 # creating needs to inherit from the parent's inner meta. Loading Loading @@ -813,7 +827,7 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None, 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): min_num=None, validate_min=False, field_classes=None): """ Returns a FormSet class for the given Django model class. """ Loading @@ -830,7 +844,8 @@ def modelformset_factory(model, form=ModelForm, formfield_callback=None, form = modelform_factory(model, form=form, fields=fields, exclude=exclude, formfield_callback=formfield_callback, 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, can_order=can_order, can_delete=can_delete, validate_min=validate_min, validate_max=validate_max) Loading Loading @@ -991,7 +1006,7 @@ def inlineformset_factory(parent_model, model, form=ModelForm, 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): min_num=None, validate_min=False, field_classes=None): """ Returns an ``InlineFormSet`` for the given kwargs. Loading Loading @@ -1020,6 +1035,7 @@ def inlineformset_factory(parent_model, model, form=ModelForm, 'labels': labels, 'help_texts': help_texts, 'error_messages': error_messages, 'field_classes': field_classes, } FormSet = modelformset_factory(model, **kwargs) FormSet.fk = fk Loading
docs/ref/forms/models.txt +22 −7 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ Model Form API reference. For introductory material about model forms, see the .. module:: django.forms.models :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``. You can optionally pass a ``form`` argument to use as a starting point for Loading @@ -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 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 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. ``labels`` is a dictionary of model field names mapped to a label. Loading @@ -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 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. You must provide the list of fields explicitly, either via keyword arguments Loading @@ -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 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. Arguments ``model``, ``form``, ``fields``, ``exclude``, ``formfield_callback``, ``widgets``, ``localized_fields``, ``labels``, ``help_texts``, and ``error_messages`` are all passed through to :func:`~django.forms.models.modelform_factory`. ``help_texts``, ``error_messages``, and ``field_classes`` are all passed through to :func:`~django.forms.models.modelform_factory`. Arguments ``formset``, ``extra``, ``max_num``, ``can_order``, ``can_delete`` and ``validate_max`` are passed through to Loading @@ -64,7 +71,11 @@ Model Form API reference. For introductory material about model forms, see the 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 defaults of ``formset=``:class:`~django.forms.models.BaseInlineFormSet`, Loading @@ -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``. See :ref:`inline-formsets` for example usage. .. versionadded:: 1.9 The ``field_classes`` keyword argument was added.
docs/releases/1.9.txt +3 −1 Original line number Diff line number Diff line Loading @@ -106,7 +106,9 @@ File Uploads 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 ^^^^^^^^^^^^^ Loading
docs/topics/forms/modelforms.txt +15 −8 Original line number Diff line number Diff line Loading @@ -475,9 +475,8 @@ Overriding the default fields 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 want that to be represented as a ``DateField`` in your form. But ``ModelForm`` gives you the flexibility of changing the form field type and widget for a given model field. want that to be represented as a ``DateField`` in your form. But ``ModelForm`` gives you the flexibility of changing the form field for a given model. 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 Loading Loading @@ -525,9 +524,8 @@ the ``name`` field:: }, } Finally, if you want complete control over of a field -- including its type, validators, etc. -- you can do this by declaratively specifying fields like you would in a regular ``Form``. You can also specify ``field_classes`` to customize the type of fields instantiated by the form. For example, if you wanted to use ``MySlugFormField`` for the ``slug`` field, you could do the following:: Loading @@ -536,13 +534,18 @@ field, you could do the following:: from myapp.models import Article class ArticleForm(ModelForm): slug = MySlugFormField() class Meta: model = Article 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 the field declaratively and setting its ``validators`` parameter:: Loading @@ -556,6 +559,10 @@ the field declaratively and setting its ``validators`` parameter:: model = Article fields = ['pub_date', 'headline', 'content', 'reporter', 'slug'] .. versionadded:: 1.9 The ``Meta.field_classes`` attribute was added. .. note:: When you explicitly instantiate a form field like this, it is important to Loading
tests/model_forms/tests.py +10 −2 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ from django.core.exceptions import ( ) from django.core.files.uploadedfile import SimpleUploadedFile 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.forms.models import ( ModelFormMetaclass, construct_instance, fields_for_model, model_to_dict, Loading Loading @@ -545,6 +545,9 @@ class FieldOverridesByFormMetaForm(forms.ModelForm): ) } } field_classes = { 'url': forms.URLField, } class TestFieldOverridesByFormMeta(TestCase): Loading Loading @@ -588,7 +591,7 @@ class TestFieldOverridesByFormMeta(TestCase): def test_error_messages_overrides(self): form = FieldOverridesByFormMetaForm(data={ 'name': 'Category', 'url': '/category/', 'url': 'http://www.example.com/category/', 'slug': '!%#*@', }) form.full_clean() Loading @@ -599,6 +602,11 @@ class TestFieldOverridesByFormMeta(TestCase): ] 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): """ Loading