Ticket #3148: 3148.diff

File 3148.diff, 3.7 KB (added by Marc Fargas, 12 years ago)

New patch using python's property(), includes docs and tests

  • django/db/models/fields/__init__.py

    === modified file 'django/db/models/fields/__init__.py'
     
    8383        core=False, rel=None, default=NOT_PROVIDED, editable=True, serialize=True,
    8484        prepopulate_from=None, unique_for_date=None, unique_for_month=None,
    8585        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):
    8787        self.name = name
    8888        self.verbose_name = verbose_name
    8989        self.primary_key = primary_key
    9090        self.max_length, self.unique = max_length, unique
    9191        self.blank, self.null = blank, null
     92        self.property = property
     93
    9294        # Oracle treats the empty string ('') as null, so coerce the null
    9395        # option whenever '' is a possible value.
    9496        if self.empty_strings_allowed and settings.DATABASE_ENGINE == 'oracle':
     
    184186        cls._meta.add_field(self)
    185187        if self.choices:
    186188            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))
    187201
    188202    def get_attname(self):
    189203        return self.name
  • docs/model-api.txt

    === modified file 'docs/model-api.txt'
     
    663663``primary_key=True`` implies ``blank=False``, ``null=False`` and
    664664``unique=True``. Only one primary key is allowed on an object.
    665665
     666``property``
     667~~~~~~~~~~~~
     668
     669It is possible to create a property around a field. It is specially usefull if
     670you want to control when the value for a field gets changed or accessed.
     671
     672The ``property`` option takes a tuple of the parameters that will be passed to
     673``property()`` to construct it.
     674
     675But note that at least getter and setter functions must be given.
     676
     677Example::
     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
    666689``radio_admin``
    667690~~~~~~~~~~~~~~~
    668691
  • tests/modeltests/properties/models.py

    === modified file 'tests/modeltests/properties/models.py'
     
    2020
    2121    full_name_2 = property(_get_full_name, _set_full_name)
    2222
     23class 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
    2332__test__ = {'API_TESTS':"""
    2433>>> a = Person(first_name='John', last_name='Lennon')
    2534>>> a.save()
     
    3746>>> a2.save()
    3847>>> a2.first_name
    3948'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'
    4060"""}
     61
Back to Top