=== modified file 'django/db/models/fields/__init__.py'
|
|
|
83 | 83 | core=False, rel=None, default=NOT_PROVIDED, editable=True, serialize=True, |
84 | 84 | prepopulate_from=None, unique_for_date=None, unique_for_month=None, |
85 | 85 | unique_for_year=None, validator_list=None, choices=None, radio_admin=None, |
86 | | help_text='', db_column=None, db_tablespace=None): |
| 86 | help_text='', db_column=None, db_tablespace=None, property=None): |
87 | 87 | self.name = name |
88 | 88 | self.verbose_name = verbose_name |
89 | 89 | self.primary_key = primary_key |
90 | 90 | self.max_length, self.unique = max_length, unique |
91 | 91 | self.blank, self.null = blank, null |
| 92 | self.property = property |
| 93 | |
92 | 94 | # Oracle treats the empty string ('') as null, so coerce the null |
93 | 95 | # option whenever '' is a possible value. |
94 | 96 | if self.empty_strings_allowed and settings.DATABASE_ENGINE == 'oracle': |
… |
… |
|
184 | 186 | cls._meta.add_field(self) |
185 | 187 | if self.choices: |
186 | 188 | setattr(cls, 'get_%s_display' % self.name, curry(cls._get_FIELD_display, field=self)) |
| 189 | if self.property: |
| 190 | while len(self.property) < 4: self.property = self.property.__add__((None, )) |
| 191 | getter = self.property[0] |
| 192 | setter = self.property[1] |
| 193 | delter = self.property[2] |
| 194 | docter = self.property[3] |
| 195 | if getter == None or setter == None: |
| 196 | # getter and setter are both needed or django will break. |
| 197 | raise ValueError("You must specify at least a getter and a setter method") |
| 198 | # Create a property on ``cls`` with the methods given. |
| 199 | setattr(cls, '%s' % self.name, |
| 200 | property(getter, setter, delter, docter)) |
187 | 201 | |
188 | 202 | def get_attname(self): |
189 | 203 | return self.name |
=== modified file 'docs/model-api.txt'
|
|
|
663 | 663 | ``primary_key=True`` implies ``blank=False``, ``null=False`` and |
664 | 664 | ``unique=True``. Only one primary key is allowed on an object. |
665 | 665 | |
| 666 | ``property`` |
| 667 | ~~~~~~~~~~~~ |
| 668 | |
| 669 | It is possible to create a property around a field. It is specially usefull if |
| 670 | you want to control when the value for a field gets changed or accessed. |
| 671 | |
| 672 | The ``property`` option takes a tuple of the parameters that will be passed to |
| 673 | ``property()`` to construct it. |
| 674 | |
| 675 | But note that at least getter and setter functions must be given. |
| 676 | |
| 677 | Example:: |
| 678 | |
| 679 | from django.db import models |
| 680 | |
| 681 | class Person(models.Model): |
| 682 | def _get_name(self): |
| 683 | return self.__name |
| 684 | def _set_name(self, value): |
| 685 | self.__name = value |
| 686 | |
| 687 | name = models.CharField(max_length=30, property=(_get_name, _set_name)) |
| 688 | |
666 | 689 | ``radio_admin`` |
667 | 690 | ~~~~~~~~~~~~~~~ |
668 | 691 | |
=== modified file 'tests/modeltests/properties/models.py'
|
|
|
20 | 20 | |
21 | 21 | full_name_2 = property(_get_full_name, _set_full_name) |
22 | 22 | |
| 23 | class PropModel(models.Model): |
| 24 | def _set_name(self, value): |
| 25 | self.__name = value |
| 26 | |
| 27 | def _get_name(self): |
| 28 | return self.__name |
| 29 | |
| 30 | name = models.CharField(max_length=30, property=(_get_name, _set_name)) |
| 31 | |
23 | 32 | __test__ = {'API_TESTS':""" |
24 | 33 | >>> a = Person(first_name='John', last_name='Lennon') |
25 | 34 | >>> a.save() |
… |
… |
|
37 | 46 | >>> a2.save() |
38 | 47 | >>> a2.first_name |
39 | 48 | 'Paul' |
| 49 | |
| 50 | # Now the field properties |
| 51 | >>> b = PropModel(name='John') |
| 52 | >>> b.save() |
| 53 | >>> b.name |
| 54 | 'John' |
| 55 | >>> b._get_name() |
| 56 | 'John' |
| 57 | >>> b.name = 'Smith' |
| 58 | >>> b._get_name() |
| 59 | 'Smith' |
40 | 60 | """} |
| 61 | |