Ticket #3148: django-modelfield-getter-setters.diff

File django-modelfield-getter-setters.diff, 3.5 KB (added by Daniel Hahler, 10 years ago)

Patch against trunk r11791 - new approach

  • django/db/models/base.py

     
    208208        else:
    209209            setattr(cls, name, value)
    210210
     211        # Add properties assigned via getter, setter and deleter field
     212        # decorators
     213        if hasattr(value, '_property') and value._property:
     214            setattr(cls, name, property(**value._property))
     215            del(value._property)
     216
    211217    def _prepare(cls):
    212218        """
    213219        Creates some methods once self._meta has been populated.
  • django/db/models/fields/__init__.py

     
    9797            self.creation_counter = Field.creation_counter
    9898            Field.creation_counter += 1
    9999
     100        self._property = {} #  stores kwargs for property ('fget', 'fset', 'fdel')
     101
    100102    def __cmp__(self, other):
    101103        # This is needed because bisect does not take a comparison function.
    102104        return cmp(self.creation_counter, other.creation_counter)
     
    148150        return self._unique or self.primary_key
    149151    unique = property(unique)
    150152
     153    def setter(self, f):
     154        self._property['fset'] = f
     155
     156    def getter(self, f):
     157        self._property['fget'] = f
     158
     159    def deleter(self, f):
     160        self._property['fdel'] = f
     161
    151162    def set_attributes_from_name(self, name):
    152163        self.name = name
    153164        self.attname, self.column = self.get_attname_column()
  • tests/regressiontests/model_fields/tests.py

     
    77from django.core.exceptions import ValidationError
    88
    99from models import Foo, Bar, Whiz, BigD, BigS, Image
     10from models import FooGetSet
    1011
    1112try:
    1213    from decimal import Decimal
     
    144145        bs = BigS.objects.create(s = 'slug'*50)
    145146        bs = BigS.objects.get(pk=bs.pk)
    146147        self.assertEqual(bs.s, 'slug'*50)
     148
     149class FieldProperties(django.test.TestCase):
     150    def test_get_set(self):
     151        """
     152        Test basic getter and setter functionality of a SlugField
     153        """
     154        f = FooGetSet( s = "test" )
     155        self.assertEqual(f.s, "test")
     156        f.s = "test2"
     157        self.assertEqual(f.s, "test2")
     158
     159        def set_non_acceptable():
     160            f.s = "not_acceptable"
     161        self.assertRaises(ValueError, set_non_acceptable)
     162        self.assertEqual(f.s, "test2")
     163
     164        f.save()
     165        f = FooGetSet.objects.get(pk=f.pk)
     166        self.assertEqual(f.s, "test2")
     167
  • tests/regressiontests/model_fields/models.py

     
    5151class BigS(models.Model):
    5252    s = models.SlugField(max_length=255)
    5353
     54class FooGetSet(models.Model):
     55    s = models.SlugField(max_length=255)
    5456
     57    @s.getter
     58    def get_s(self):
     59        return self._s
     60    @s.setter
     61    def set_s(self, value):
     62        if value is "not_acceptable":
     63            raise ValueError("not acceptable")
     64        self._s = value
     65
    5566###############################################################################
    5667# ImageField
    5768
Back to Top