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 | |