diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index 8803375..b4947e8 100644
a
|
b
|
class Field(object):
|
89 | 89 | editable=True, serialize=True, prepopulate_from=None, |
90 | 90 | unique_for_date=None, unique_for_month=None, unique_for_year=None, |
91 | 91 | validator_list=None, choices=None, radio_admin=None, help_text='', |
92 | | db_column=None, db_tablespace=None, auto_created=False): |
| 92 | db_column=None, db_tablespace=None, auto_created=False, use_property=None): |
93 | 93 | self.name = name |
94 | 94 | self.verbose_name = verbose_name |
95 | 95 | self.primary_key = primary_key |
96 | 96 | self.max_length, self.unique = max_length, unique |
97 | 97 | self.blank, self.null = blank, null |
| 98 | self.model_property = use_property |
98 | 99 | # Oracle treats the empty string ('') as null, so coerce the null |
99 | 100 | # option whenever '' is a possible value. |
100 | 101 | if self.empty_strings_allowed and settings.DATABASE_ENGINE == 'oracle': |
… |
… |
class Field(object):
|
202 | 203 | cls._meta.add_field(self) |
203 | 204 | if self.choices: |
204 | 205 | setattr(cls, 'get_%s_display' % self.name, curry(cls._get_FIELD_display, field=self)) |
| 206 | if self.model_property: |
| 207 | if len(self.model_property) < 2: |
| 208 | raise ValueError("You must specify at least a getter and a setter method") |
| 209 | # Create a property on ``cls`` with the methods given. |
| 210 | setattr(cls, '%s' % self.name, |
| 211 | property(*self.model_property)) |
205 | 212 | |
206 | 213 | def get_attname(self): |
207 | 214 | return self.name |
diff --git a/docs/model-api.txt b/docs/model-api.txt
index 4ed4ede..1e1129a 100644
a
|
b
|
unless you want to override the default primary-key behavior.
|
665 | 665 | ``primary_key=True`` implies ``blank=False``, ``null=False`` and |
666 | 666 | ``unique=True``. Only one primary key is allowed on an object. |
667 | 667 | |
| 668 | ``use_property`` |
| 669 | ~~~~~~~~~~~~~~~~ |
| 670 | |
| 671 | It is possible to create a property around a field. It is specially usefull if |
| 672 | you want to control when the value for a field gets changed or accessed. |
| 673 | |
| 674 | The ``use_property`` option takes a tuple of the parameters that will be passed to |
| 675 | ``property()`` to construct it. |
| 676 | |
| 677 | But note that at least getter and setter functions must be given. |
| 678 | |
| 679 | Example:: |
| 680 | |
| 681 | from django.db import models |
| 682 | |
| 683 | class Person(models.Model): |
| 684 | def _get_name(self): |
| 685 | return self.__name |
| 686 | def _set_name(self, value): |
| 687 | self.__name = value |
| 688 | |
| 689 | name = models.CharField(max_length=30, use_property=(_get_name, _set_name)) |
| 690 | |
668 | 691 | ``radio_admin`` |
669 | 692 | ~~~~~~~~~~~~~~~ |
670 | 693 | |
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 | |