Fixed #22537 -- Add tests and improved docs for field subclass with choices.

This commit is contained in:
Mike Fogel 2014-04-11 23:58:56 -04:00 committed by Tim Graham
parent 8ec388a69d
commit 7fd1b35ed7
4 changed files with 30 additions and 5 deletions

View File

@ -83,8 +83,8 @@ two items (e.g. ``[(A, B), (A, B) ...]``) to use as choices for this field. If
this is given, the default form widget will be a select box with these choices
instead of the standard text field.
The first element in each tuple is the actual value to be stored, and the
second element is the human-readable name. For example::
The first element in each tuple is the actual value to be set on the model,
and the second element is the human-readable name. For example::
YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'),

View File

@ -20,6 +20,11 @@ class Small(object):
def __str__(self):
return '%s%s' % (force_text(self.first), force_text(self.second))
def __eq__(self, other):
if isinstance(other, self.__class__):
return self.first == other.first and self.second == other.second
return False
class SmallField(six.with_metaclass(models.SubfieldBase, models.Field)):
"""

View File

@ -5,7 +5,7 @@ Tests for field subclassing.
from django.db import models
from django.utils.encoding import force_text
from .fields import SmallField, SmallerField, JSONField
from .fields import Small, SmallField, SmallerField, JSONField
from django.utils.encoding import python_2_unicode_compatible
@ -22,5 +22,15 @@ class OtherModel(models.Model):
data = SmallerField()
class ChoicesModel(models.Model):
SMALL_AB = Small('a', 'b')
SMALL_CD = Small('c', 'd')
SMALL_CHOICES = (
(SMALL_AB, str(SMALL_AB)),
(SMALL_CD, str(SMALL_CD)),
)
data = SmallField('small field', choices=SMALL_CHOICES)
class DataModel(models.Model):
data = JSONField()

View File

@ -2,12 +2,12 @@ from __future__ import unicode_literals
import inspect
from django.core import serializers
from django.core import exceptions, serializers
from django.db import connection
from django.test import TestCase
from .fields import Small, CustomTypedField
from .models import DataModel, MyModel, OtherModel
from .models import ChoicesModel, DataModel, MyModel, OtherModel
class CustomField(TestCase):
@ -106,6 +106,16 @@ class CustomField(TestCase):
self.assertIn('__module__', data)
self.assertEqual(data['__module__'], 'field_subclassing.models')
def test_validation_of_choices_for_custom_field(self):
# a valid choice
o = ChoicesModel.objects.create(data=Small('a', 'b'))
o.full_clean()
# an invalid choice
o = ChoicesModel.objects.create(data=Small('d', 'e'))
with self.assertRaises(exceptions.ValidationError):
o.full_clean()
class TestDbType(TestCase):