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:
parent
352deb0915
commit
222c732616
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in New Issue