Ticket #15126: django15126.testfields.diff

File django15126.testfields.diff, 3.1 KB (added by anonymous, 4 years ago)
  • tests/regressiontests/forms/tests/models.py

     
    11# -*- coding: utf-8 -*-
    22import datetime
    33from django.core.files.uploadedfile import SimpleUploadedFile
     4from django.core.exceptions import FieldError
    45from django.forms import Form, ModelForm, FileField, ModelChoiceField
    56from django.test import TestCase
    67from regressiontests.forms.models import ChoiceModel, ChoiceOptionModel, ChoiceFieldModel, FileModel, Group, BoundaryModel, Defaults
     
    159160        self.assertEqual(obj.name, u'class default value')
    160161        self.assertEqual(obj.value, 99)
    161162        self.assertEqual(obj.def_date, datetime.date(1999, 3, 2))
     163
     164    def test_fields_validation(self):
     165        """ Test whether 'fields' and 'exclude' options are validated #15126 """
     166
     167        class ValidModelForm(ModelForm):
     168            class Meta:
     169                model = Defaults
     170                fields = ('name', )
     171                exclude = ('value', )
     172
     173        valid_form = ValidModelForm()
     174        self.assertEqual(valid_form._meta.fields, ('name', ))
     175
     176        try:
     177            class InvalidFieldsModelForm(ModelForm):
     178                class Meta:
     179                    model = Defaults
     180                    fields = ('name') # Not a valid list, but a string
     181            self.fail('Incorrect "fields"-option type not detected on ModelForm')
     182        except TypeError: # correct TypeError
     183            pass
     184        except FieldError: # missing field because of faulty typing
     185            self.fail('Incorrect "fields"-option type not detected on ModelForm')
     186
     187        try:
     188            class InvalidExcludeModelForm(ModelForm):
     189                class Meta:
     190                    model = Defaults
     191                    exclude = ('name') # Not a valid list, but a string
     192            self.fail('Incorrect "exclude"-option type not detected on ModelForm')
     193        except TypeError: # correct TypeError
     194            pass
  • django/forms/models.py

     
    200200        if 'media' not in attrs:
    201201            new_class.media = media_property(new_class)
    202202        opts = new_class._meta = ModelFormOptions(getattr(new_class, 'Meta', None))
     203
     204        def _check_option_iterable(option):
     205            """ Check whether option is a valid iterable and retrieve from options (#15126) """
     206            value = getattr(opts, option, None)
     207            if value is not None and isinstance(value, str):
     208                raise TypeError('Option "%s" on %s must be a valid list'
     209                    ', not "%s".' % (option, new_class.__name__, type(value).__name__))
     210
     211        _check_option_iterable('fields')
     212        _check_option_iterable('exclude')
     213       
    203214        if opts.model:
    204215            # If a model is defined, extract form fields from it.
    205216            fields = fields_for_model(opts.model, opts.fields,
Back to Top