Ticket #15184: foreignkey_subclass_patch.diff
File foreignkey_subclass_patch.diff, 4.3 KB (added by , 14 years ago) |
---|
-
django/db/models/fields/subclassing.py
22 22 """ 23 23 A placeholder class that provides a way to set the attribute on the model. 24 24 """ 25 def __init__(self, field ):25 def __init__(self, field, old_descr=None): 26 26 self.field = field 27 self.old_descr = old_descr 27 28 28 29 def __get__(self, obj, type=None): 29 30 if obj is None: 30 31 raise AttributeError('Can only be accessed via an instance.') 31 return obj.__dict__[self.field.name] 32 if self.old_descr: 33 return self.old_descr.__get__(obj, type) 34 else: 35 return obj.__dict__[self.field.name] 32 36 33 37 def __set__(self, obj, value): 34 obj.__dict__[self.field.name] = self.field.to_python(value) 38 val = self.field.to_python(value) 39 if self.old_descr: 40 self.old_descr.__set__(obj, val) 41 else: 42 obj.__dict__[self.field.name] = val 35 43 36 44 def make_contrib(superclass, func=None): 37 45 """ … … 47 55 func(self, cls, name) 48 56 else: 49 57 super(superclass, self).contribute_to_class(cls, name) 50 setattr(cls, self.name, Creator(self)) 58 # If this value already exists on the class it is likely a descriptor 59 # for related fields. Keep it around so we can call it from our 60 # descriptor. 61 old_descr = cls.__dict__.get(self.name) 62 setattr(cls, self.name, Creator(self, old_descr)) 51 63 52 64 return contribute_to_class -
tests/modeltests/field_subclassing/tests.py
1 1 from django.core import serializers 2 2 from django.test import TestCase 3 from django.core.exceptions import ObjectDoesNotExist 3 4 4 5 from fields import Small 5 from models import DataModel, MyModel, OtherModel 6 from models import DataModel, MyModel, OtherModel, FKModel 6 7 7 8 8 9 class CustomField(TestCase): … … 79 80 o = OtherModel.objects.get() 80 81 self.assertEqual(o.data.first, "a") 81 82 self.assertEqual(o.data.second, "b") 83 84 def test_foreignkey_subclassing(self): 85 obj = FKModel() 86 87 # We have to do something a bit funky to catch this exception due to 88 # it originating in a descriptor. 89 okay = False 90 try: 91 # The next line would have raised a KeyError prior to being fixed. 92 val = obj.data 93 except ObjectDoesNotExist: 94 okay = True 95 self.assertEquals(okay, True) 96 97 target = MyModel.objects.create(name="1", data=Small(1, 2)) 98 obj.data = target 99 obj.save() 100 self.assertEqual(obj.data, target) -
tests/modeltests/field_subclassing/models.py
5 5 from django.db import models 6 6 from django.utils.encoding import force_unicode 7 7 8 from fields import Small, SmallField, SmallerField, JSONField 8 from fields import Small, SmallField, SmallerField, JSONField, FKSubField 9 9 10 10 11 11 class MyModel(models.Model): … … 20 20 21 21 class DataModel(models.Model): 22 22 data = JSONField() 23 24 25 class FKModel(models.Model): 26 data = FKSubField(MyModel) -
tests/modeltests/field_subclassing/fields.py
71 71 if value is None: 72 72 return None 73 73 return json.dumps(value) 74 75 76 class FKSubField(models.ForeignKey): 77 """ 78 Subclass ForeignKey to check descriptor overloading. Confirms ticket 79 #15184 has been corrected. 80 """ 81 __metaclass__ = models.SubfieldBase 82 83 def __init__(self, cls, *args, **kwargs): 84 super(FKSubField, self).__init__(cls, *args, **kwargs) 85 86 def to_python(self, value): 87 return value