diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index b0dd55e..ce8aed3 100644
a
|
b
|
class Field(object):
|
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, use_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.model_property = use_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': |
… |
… |
class Field(object):
|
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.model_property: |
| 190 | if len(self.model_property) < 2: |
| 191 | raise ValueError("You must specify at least a getter and a setter method") |
| 192 | # Create a property on ``cls`` with the methods given. |
| 193 | setattr(cls, '%s' % self.name, |
| 194 | property(*self.model_property)) |
187 | 195 | |
188 | 196 | def get_attname(self): |
189 | 197 | return self.name |
diff --git a/docs/model-api.txt b/docs/model-api.txt
index ca84c84..ced50e4 100644
a
|
b
|
unless you want to override the default primary-key behavior.
|
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 | ``use_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 ``use_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, use_property=(_get_name, _set_name)) |
| 688 | |
666 | 689 | ``radio_admin`` |
667 | 690 | ~~~~~~~~~~~~~~~ |
668 | 691 | |
diff --git a/tests/modeltests/properties/models.py b/tests/modeltests/properties/models.py
index 5326e4e..9aa2c55 100644
a
|
b
|
class Person(models.Model):
|
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, use_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() |
… |
… |
AttributeError: can't set attribute
|
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 | |