Ticket #9245: 9245.more-flexible-formfield.diff

File 9245.more-flexible-formfield.diff, 4.2 KB (added by julien, 3 years ago)
  • django/db/models/fields/__init__.py

    diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
    index 9db76a6..2509ddb 100644
    a b class Field(object): 
    474474            else:
    475475                defaults['initial'] = self.get_default()
    476476        if self.choices:
    477             # Fields with choices get special treatment.
    478477            include_blank = (self.blank or
    479478                             not (self.has_default() or 'initial' in kwargs))
    480479            defaults['choices'] = self.get_choices(include_blank=include_blank)
     480            defaults.update(kwargs)
     481            return self.choices_formfield(**defaults)
     482        else:
     483            defaults.update(kwargs)
     484            return form_class(**defaults)
     485
     486    def choices_formfield(self, form_class=None, **kwargs):
     487        defaults = {}
     488        if form_class is None:
     489            form_class = forms.TypedChoiceField
    481490            defaults['coerce'] = self.to_python
    482491            if self.null:
    483492                defaults['empty_value'] = None
    484             form_class = forms.TypedChoiceField
    485493            # Many of the subclass-specific formfield arguments (min_value,
    486494            # max_value) don't apply for choice fields, so be sure to only pass
    487495            # the values that TypedChoiceField will understand.
  • tests/regressiontests/model_fields/models.py

    diff --git a/tests/regressiontests/model_fields/models.py b/tests/regressiontests/model_fields/models.py
    index 4dcfb17..f3e18ca 100644
    a b except ImportError: 
    1313    except ImportError:
    1414        Image = None
    1515
     16from django import forms
    1617from django.core.files.storage import FileSystemStorage
    1718from django.db import models
    1819from django.db.models.fields.files import ImageFieldFile, ImageField
    class Bar(models.Model): 
    2930    b = models.CharField(max_length=10)
    3031    a = models.ForeignKey(Foo, default=get_foo)
    3132
     33class CustomIntegerFormField(forms.IntegerField):
     34    def __init__(self, *args, **kwargs):
     35        if 'choices' in kwargs:
     36            del kwargs['choices']
     37        super(CustomIntegerFormField, self).__init__(*args, **kwargs)
     38
     39class CustomIntegerField(models.IntegerField):
     40    def choices_formfield(self, form_class=None, **kwargs):
     41        return super(CustomIntegerField, self).choices_formfield(
     42            form_class=CustomIntegerFormField, **kwargs)
     43
    3244class Whiz(models.Model):
    3345    CHOICES = (
    3446        ('Group 1', (
    class Whiz(models.Model): 
    4456        (0,'Other'),
    4557    )
    4658    c = models.IntegerField(choices=CHOICES, null=True)
     59    d = CustomIntegerField(choices=CHOICES, default=4)
     60    ts = models.DateTimeField(auto_now_add=True)
    4761
    4862class BigD(models.Model):
    4963    d = models.DecimalField(max_digits=38, decimal_places=30)
  • tests/regressiontests/model_fields/tests.py

    diff --git a/tests/regressiontests/model_fields/tests.py b/tests/regressiontests/model_fields/tests.py
    index 5d3d42e..1493963 100644
    a b from django.db.models.fields.files import FieldFile 
    1111from django.utils import unittest
    1212
    1313from .models import (Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post,
    14     NullBooleanModel, BooleanModel, Document, RenamedField)
     14    NullBooleanModel, BooleanModel, Document, RenamedField,
     15    CustomIntegerFormField)
    1516
    1617# If PIL available, do these tests.
    1718if Image:
    class ChoicesTests(test.TestCase): 
    223224        self.assertEqual(Whiz(c=None).get_c_display(), None)    # Blank value
    224225        self.assertEqual(Whiz(c='').get_c_display(), '')        # Empty value
    225226
     227    def test_choices_formfield_overrides(self):
     228        whiz_meta = Whiz(c=1)._meta
     229        field = whiz_meta.get_field_by_name('c')[0]
     230        self.assertIs(type(field.formfield()),
     231                forms.TypedChoiceField)
     232        self.assertIs(type(whiz_meta.get_field_by_name('d')[0].formfield()),
     233                CustomIntegerFormField)
     234        self.assertIs(type(whiz_meta.get_field_by_name('ts')[0].formfield()),
     235                forms.DateTimeField)
     236
    226237class SlugFieldTests(test.TestCase):
    227238    def test_slugfield_max_length(self):
    228239        """
Back to Top