Fixed #10728 -- corrected subclassing of Fields who use the SubfieldBase metaclass. Thanks to G2P and George Sakkis for their work on the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14443 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Alex Gaynor 2010-11-02 18:40:53 +00:00
parent 352deb0915
commit 222c732616
4 changed files with 18 additions and 5 deletions

View File

@ -79,7 +79,8 @@ class SubfieldBase(LegacyConnection):
def __new__(cls, base, name, attrs): def __new__(cls, base, name, attrs):
new_class = super(SubfieldBase, cls).__new__(cls, base, name, attrs) new_class = super(SubfieldBase, cls).__new__(cls, base, name, attrs)
new_class.contribute_to_class = make_contrib( new_class.contribute_to_class = make_contrib(
attrs.get('contribute_to_class')) new_class, attrs.get('contribute_to_class')
)
return new_class return new_class
class Creator(object): class Creator(object):
@ -97,7 +98,7 @@ class Creator(object):
def __set__(self, obj, value): def __set__(self, obj, value):
obj.__dict__[self.field.name] = self.field.to_python(value) obj.__dict__[self.field.name] = self.field.to_python(value)
def make_contrib(func=None): def make_contrib(superclass, func=None):
""" """
Returns a suitable contribute_to_class() method for the Field subclass. Returns a suitable contribute_to_class() method for the Field subclass.
@ -110,7 +111,7 @@ def make_contrib(func=None):
if func: if func:
func(self, cls, name) func(self, cls, name)
else: else:
super(self.__class__, self).contribute_to_class(cls, name) super(superclass, self).contribute_to_class(cls, name)
setattr(cls, self.name, Creator(self)) setattr(cls, self.name, Creator(self))
return contribute_to_class return contribute_to_class

View File

@ -52,6 +52,9 @@ class SmallField(models.Field):
return [] return []
raise TypeError('Invalid lookup type: %r' % lookup_type) raise TypeError('Invalid lookup type: %r' % lookup_type)
class SmallerField(SmallField):
pass
class JSONField(models.TextField): class JSONField(models.TextField):
__metaclass__ = models.SubfieldBase __metaclass__ = models.SubfieldBase

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_unicode from django.utils.encoding import force_unicode
from fields import Small, SmallField, JSONField from fields import Small, SmallField, SmallerField, JSONField
class MyModel(models.Model): class MyModel(models.Model):
@ -15,5 +15,8 @@ class MyModel(models.Model):
def __unicode__(self): def __unicode__(self):
return force_unicode(self.name) return force_unicode(self.name)
class OtherModel(models.Model):
data = SmallerField()
class DataModel(models.Model): class DataModel(models.Model):
data = JSONField() data = JSONField()

View File

@ -2,7 +2,7 @@ from django.core import serializers
from django.test import TestCase from django.test import TestCase
from fields import Small from fields import Small
from models import DataModel, MyModel from models import DataModel, MyModel, OtherModel
class CustomField(TestCase): class CustomField(TestCase):
@ -73,3 +73,9 @@ class CustomField(TestCase):
], ],
lambda m: str(m.data) lambda m: str(m.data)
) )
def test_field_subclassing(self):
o = OtherModel.objects.create(data=Small("a", "b"))
o = OtherModel.objects.get()
self.assertEqual(o.data.first, "a")
self.assertEqual(o.data.second, "b")