Ticket #3148: revised.add.getter.setter.patch
File revised.add.getter.setter.patch, 6.2 KB (added by , 18 years ago) |
---|
-
django/db/models/base.py
90 90 91 91 def __init__(self, *args, **kwargs): 92 92 dispatcher.send(signal=signals.pre_init, sender=self.__class__, args=args, kwargs=kwargs) 93 self._django_initializing = True 93 94 for f in self._meta.fields: 94 95 if isinstance(f.rel, ManyToOneRel): 95 96 try: … … 127 128 setattr(self, self._meta.fields[i].attname, arg) 128 129 dispatcher.send(signal=signals.post_init, sender=self.__class__, instance=self) 129 130 131 del self._django_initializing 132 130 133 def add_to_class(cls, name, value): 131 134 if name == 'Admin': 132 135 assert type(value) == types.ClassType, "%r attribute of %s model must be a class, not a %s object" % (name, cls.__name__, type(value)) -
django/db/models/fields/__init__.py
70 70 core=False, rel=None, default=NOT_PROVIDED, editable=True, 71 71 prepopulate_from=None, unique_for_date=None, unique_for_month=None, 72 72 unique_for_year=None, validator_list=None, choices=None, radio_admin=None, 73 help_text='', db_column=None ):73 help_text='', db_column=None, getter=None, setter=None): 74 74 self.name = name 75 75 self.verbose_name = verbose_name 76 76 self.primary_key = primary_key … … 86 86 self.radio_admin = radio_admin 87 87 self.help_text = help_text 88 88 self.db_column = db_column 89 self.getter = getter 90 self.setter = setter 89 91 90 92 # Set db_index to True if the field has a relationship and doesn't explicitly set db_index. 91 93 self.db_index = db_index … … 139 141 cls._meta.add_field(self) 140 142 if self.choices: 141 143 setattr(cls, 'get_%s_display' % self.name, curry(cls._get_FIELD_display, field=self)) 144 if self.setter is not None or self.getter is not None: 145 self.create_property_on_class(cls) 142 146 147 def create_property_on_class(self, cls): 148 """create the property to support setters and getters""" 149 name = self.name 150 field_att = "_%s" % name 151 152 if self.getter: 153 getter_name = self.getter 154 def get_func(self): 155 value = getattr(self, field_att) 156 return getattr(self, getter_name)(value) 157 else: 158 def get_func(self): 159 return getattr(self, field_att) 160 161 if self.setter: 162 setter_name = self.setter 163 def set_func(self, value): 164 if hasattr(self, '_django_initializing'): 165 setattr(self, field_att, value) 166 else: 167 setattr(self, field_att, 168 getattr(self, setter_name)(value)) 169 else: 170 def set_func(self, value): 171 setattr(self, field_att, value) 172 173 setattr(cls, name, property(get_func, set_func)) 174 143 175 def get_attname(self): 144 176 return self.name 145 177 -
tests/modeltests/getters_setters/models.py
1 """ 2 Test the 'getter' and 'setter' functionality on fields. 3 4 This tests a field with a setter, a field with a getter, and a field 5 with both. Since the getter/setter implementation is at the Field 6 level, and I've verified that all Field objects pass through the code 7 that constructs these properties, I believe it would be redundent to 8 test all the Field Types individually. 9 10 Doc note: Setters 11 """ 12 13 from django.db import models 14 15 class GetSet(models.Model): 16 has_getter = models.CharField(maxlength=20, getter='simple_getter') 17 has_setter = models.CharField(maxlength=20, setter='simple_setter') 18 has_both = models.CharField(maxlength=20, getter='simple_getter', 19 setter='updater') 20 updated_length_field = models.IntegerField(default=0) 21 22 def simple_getter(self, value): 23 return value + "_getter" 24 def simple_setter(self, value): 25 return value + "_setter" 26 def updater(self, value): 27 self.updated_length_field = len(value) 28 return value 29 30 31 __test__ = {'API_TESTS':""" 32 >>> a = GetSet(has_getter='x', has_setter='y', has_both='z') 33 >>> a.has_getter 34 'x_getter' 35 >>> a.has_setter 36 'y' 37 >>> a.has_both 38 'z_getter' 39 40 # Setter has not run yet 41 42 >>> a.updated_length_field 43 0 44 >>> a.has_both = 'abcd' 45 >>> a.updated_length_field 46 4 47 >>> a.save() 48 >>> a_id = a.id 49 >>> del a 50 >>> a = GetSet.objects.get(id=a_id) 51 >>> a.updated_length_field 52 4 53 """} 54 55 -
docs/model-api.txt
548 548 processing using the object's ``AddManipulator`` or ``ChangeManipulator`` 549 549 classes. Default is ``True``. 550 550 551 ``getter`` 552 ~~~~~~~~~~ 553 554 A string indicating a method of the class to call when you try 555 to retrieve the value of the field. The method will be passed as its 556 only argument the current "underlying value" of the field (as received 557 from the database, object construction, or previous setting 558 operation), and the return value of that method is what the user 559 receives. 560 551 561 ``help_text`` 552 562 ~~~~~~~~~~~~~ 553 563 … … 581 591 Don't use this for a field unless it's a ``ForeignKey`` or has ``choices`` 582 592 set. 583 593 594 ``setter`` 595 ~~~~~~~~~~ 596 597 A string indicating a method of the class to call when you try to set 598 the value of the field. The method will be passed as its only argument 599 the value the user is setting the field to, and the return value is 600 what will actually be set in the database. 601 602 The setter will not be run when the object is created, either by 603 database retrieval or construction. 604 584 605 ``unique`` 585 606 ~~~~~~~~~~ 586 607