Ticket #9245: 9245.2.diff

File 9245.2.diff, 6.2 KB (added by badri, 7 years ago)
  • django/db/models/fields/__init__.py

     
    313313            include_blank = self.blank or not (self.has_default() or 'initial' in kwargs)
    314314            defaults['choices'] = self.get_choices(include_blank=include_blank)
    315315            defaults['coerce'] = self.to_python
    316             if self.null:
    317                 defaults['empty_value'] = None
    318             form_class = forms.TypedChoiceField
     316            if form_class in (forms.CharField, forms.BooleanField,forms.IntegerField, forms.RegexField,
     317                              forms.TypedChoiceField, forms.NullBooleanField):
     318                 form_class = forms.TypedChoiceField
     319                 if self.null:
     320                    defaults['empty_value'] = None
    319321            # Many of the subclass-specific formfield arguments (min_value,
    320322            # max_value) don't apply for choice fields, so be sure to only pass
    321323            # the values that TypedChoiceField will understand.
  • tests/regressiontests/forms/tests.py

     
    3030from widgets import tests as widgets_tests
    3131from formsets import tests as formset_tests
    3232from media import media_tests
     33from forms import custom_form_field_tests
    3334
    3435__test__ = {
    3536    'extra_tests': extra_tests,
     
    6364    'media_tests': media_tests,
    6465    'util_tests': util_tests,
    6566    'widgets_tests': widgets_tests,
     67    'custom_form_field_tests': custom_form_field_tests,
    6668}
    6769
    6870if __name__ == "__main__":
  • tests/regressiontests/forms/models.py

     
    55# Can't import as "forms" due to implementation details in the test suite (the
    66# current file is called "forms" and is already imported).
    77from django import forms as django_forms
     8from django.utils.encoding import force_unicode
    89
    910class BoundaryModel(models.Model):
    1011    positive_integer = models.PositiveIntegerField(null=True, blank=True)
     
    2425class FileForm(django_forms.Form):
    2526    file1 = django_forms.FileField()
    2627
     28# models for custom form fields, regress for #9245
     29from django.forms import fields
     30class CustomFormField(fields.TypedChoiceField):
     31    def __init__(self, *args, **kwargs):
     32        super(CustomFormField, self).__init__(*args, **kwargs)
     33
     34    def clean(self, value):
     35        return super(CustomFormField, self).clean(value)
     36
     37# a trivial object to be stored in db
     38class Small(object):
     39    def __init__(self, first, second):
     40        self.first, self.second = first, second
     41
     42    def __unicode__(self):
     43        return u'%s%s' % (force_unicode(self.first), force_unicode(self.second))
     44
     45    def __str__(self):
     46        return unicode(self).encode('utf-8')
     47
     48# create a custom field upon 'Small' and associate with a custom form field
     49class SmallField(models.Field):
     50    __metaclass__ = models.SubfieldBase
     51
     52    def __init__(self, *args, **kwargs):
     53        kwargs['max_length'] = 2
     54        super(SmallField, self).__init__(*args, **kwargs)
     55
     56    def get_internal_type(self):
     57        return 'CharField'
     58
     59    def to_python(self, value):
     60        if isinstance(value, Small):
     61            return value
     62        return Small(value[0], value[1])
     63
     64    def get_db_prep_save(self, value):
     65        return unicode(value)
     66
     67    def get_db_prep_lookup(self, lookup_type, value):
     68        if lookup_type == 'exact':
     69            return force_unicode(value)
     70        if lookup_type == 'in':
     71            return [force_unicode(v) for v in value]
     72        if lookup_type == 'isnull':
     73            return []
     74        raise FieldError('Invalid lookup type: %r' % lookup_type)
     75
     76    def formfield(self, **kwargs):
     77        return super(SmallField, self).formfield(form_class = CustomFormField, **kwargs)
     78        return super(SmallField, self).formfield(**kwargs)
     79
     80# use SmallField in a model
     81class MyModel(models.Model):
     82    name = models.CharField(max_length=10)
     83    MY_CHOICES  = (
     84        ('AB', 'ab'),
     85        ('CD', 'cd'),
     86        ('EF', 'ef'),
     87    )
     88    data = SmallField('small field',choices = MY_CHOICES)
     89
     90    def __unicode__(self):
     91        return force_unicode(self.name)
     92
    2793__test__ = {'API_TESTS': """
    2894>>> from django.forms.models import ModelForm
    2995>>> from django.core.files.uploadedfile import SimpleUploadedFile
  • tests/regressiontests/forms/forms.py

     
    17501750True
    17511751
    17521752"""
     1753custom_form_field_tests = r"""
     1754>>> from regressiontests.forms.models import MyModel
     1755>>> from regressiontests.forms.models import Small
     1756>>> s = Small('A', 'B')
     1757>>> MyModel.objects.create(pk=1, name='abc', data = s)
     1758<MyModel: abc>
     1759>>> from django.forms import ModelForm
     1760>>> class MyModelForm(ModelForm):
     1761...     class Meta:
     1762...         model = MyModel
     1763...
     1764>>> mymodel_form = MyModelForm(instance = MyModel.objects.get(id=1))
     1765>>> print mymodel_form['data']
     1766<select name="data" id="id_data">
     1767<option value="">---------</option>
     1768<option value="AB" selected="selected">ab</option>
     1769<option value="CD">cd</option>
     1770<option value="EF">ef</option>
     1771</select>
     1772>>> from regressiontests.forms.models import SmallField
     1773>>> small_field = SmallField('a simple small field', choices = MyModel.MY_CHOICES)
     1774>>> small_field.formfield().__class__
     1775<class 'regressiontests.forms.models.CustomFormField'>
     1776>>> small_field = SmallField('small field without choices')
     1777>>> small_field.formfield().__class__
     1778<class 'regressiontests.forms.models.CustomFormField'>
     1779>>> from django.db import models
     1780>>> regular_field = models.CharField(max_length=2, choices = MyModel.MY_CHOICES)
     1781>>> regular_field.formfield().__class__
     1782<class 'django.forms.fields.TypedChoiceField'>
     1783>>> regular_field = models.CharField(max_length=10)
     1784>>> regular_field.formfield().__class__
     1785<class 'django.forms.fields.CharField'>
     1786"""
Back to Top