Ticket #3148: revised2.add.getter.setter.patch
File revised2.add.getter.setter.patch, 7.0 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 35. Getters and setters 3 4 Each field can have a 'getter' and a 'setter'. 5 6 The getter can modify the values received from the database. A 7 method is specified as a string that names it. When the user of 8 your model requests that field, the 'getter' will be called with the 9 current database value of the field, and what is returned by the 10 method is what the user will receive as the value of the field. 11 12 The setter can modify the value of the field before it is sent to the 13 database. A method is specified as a string that names it. When the 14 user of your model sets that field, the 'setter' will be called with 15 the value the user is setting, and what is returned by the setter is 16 what will be saved in the database. 17 18 If you return the same value that came in, you can use a 'setter' as a 19 hook to update other pieces of data when the value of the field 20 changes. 21 22 Setters do not run during construction. 23 """ 24 25 from django.db import models 26 27 class GetSet(models.Model): 28 has_getter = models.CharField(maxlength=20, getter='simple_getter') 29 has_setter = models.CharField(maxlength=20, setter='simple_setter') 30 has_both = models.CharField(maxlength=20, getter='simple_getter', 31 setter='updater') 32 updated_length_field = models.IntegerField(default=0) 33 34 def simple_getter(self, value): 35 return value + "_getter" 36 def simple_setter(self, value): 37 return value + "_setter" 38 def updater(self, value): 39 self.updated_length_field = len(value) 40 return value 41 42 43 __test__ = {'API_TESTS':""" 44 >>> a = GetSet(has_getter='x', has_setter='y', has_both='z') 45 46 # The getter filters the 'x' 47 >>> a.has_getter 48 'x_getter' 49 50 # The setter does not run during construction. 51 >>> a.has_setter 52 'y' 53 >>> a.has_both 54 'z_getter' 55 56 # Setter has not run yet, so the updated_length_field has not been set 57 >>> a.updated_length_field 58 0 59 >>> a.has_both = 'abcd' 60 61 # Now the setter has been called. 62 >>> a.updated_length_field 63 4 64 >>> a.save() 65 >>> a_id = a.id 66 >>> del a 67 68 # And we can see the new updated_length_field was indeed saved in the 69 # database. 70 >>> a = GetSet.objects.get(id=a_id) 71 >>> a.updated_length_field 72 4 73 """} 74 75 -
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