[1.7.x] Fixed #22537 -- Add tests and improved docs for field subclass with choices.

Backport of 7fd1b35ed7 from master
This commit is contained in:
Mike Fogel 2014-04-11 23:58:56 -04:00 committed by Tim Graham
parent 6d4df45e29
commit bb5c7e4e8d
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 this is given, the default form widget will be a select box with these choices
instead of the standard text field. instead of the standard text field.
The first element in each tuple is the actual value to be stored, and the The first element in each tuple is the actual value to be set on the model,
second element is the human-readable name. For example:: and the second element is the human-readable name. For example::
YEAR_IN_SCHOOL_CHOICES = ( YEAR_IN_SCHOOL_CHOICES = (
('FR', 'Freshman'), ('FR', 'Freshman'),

View File

@ -20,6 +20,11 @@ class Small(object):
def __str__(self): def __str__(self):
return '%s%s' % (force_text(self.first), force_text(self.second)) 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)): 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.db import models
from django.utils.encoding import force_text 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 from django.utils.encoding import python_2_unicode_compatible
@ -22,5 +22,15 @@ class OtherModel(models.Model):
data = SmallerField() 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): class DataModel(models.Model):
data = JSONField() data = JSONField()

View File

@ -2,12 +2,12 @@ from __future__ import unicode_literals
import inspect import inspect
from django.core import serializers from django.core import exceptions, serializers
from django.db import connection from django.db import connection
from django.test import TestCase from django.test import TestCase
from .fields import Small, CustomTypedField from .fields import Small, CustomTypedField
from .models import DataModel, MyModel, OtherModel from .models import ChoicesModel, DataModel, MyModel, OtherModel
class CustomField(TestCase): class CustomField(TestCase):
@ -106,6 +106,16 @@ class CustomField(TestCase):
self.assertIn('__module__', data) self.assertIn('__module__', data)
self.assertEqual(data['__module__'], 'field_subclassing.models') 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): class TestDbType(TestCase):