Loading docs/ref/models/fields.txt +2 −2 Original line number Diff line number Diff line Loading @@ -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'), Loading tests/field_subclassing/fields.py +5 −0 Original line number Diff line number Diff line Loading @@ -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)): """ Loading tests/field_subclassing/models.py +11 −1 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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() tests/field_subclassing/tests.py +12 −2 Original line number Diff line number Diff line Loading @@ -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): Loading Loading @@ -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): Loading Loading
docs/ref/models/fields.txt +2 −2 Original line number Diff line number Diff line Loading @@ -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'), Loading
tests/field_subclassing/fields.py +5 −0 Original line number Diff line number Diff line Loading @@ -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)): """ Loading
tests/field_subclassing/models.py +11 −1 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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()
tests/field_subclassing/tests.py +12 −2 Original line number Diff line number Diff line Loading @@ -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): Loading Loading @@ -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): Loading