代码之家  ›  专栏  ›  技术社区  ›  pistacchio

Django模型字段getter/setter

  •  20
  • pistacchio  · 技术社区  · 15 年前

    对于django模型的字段是否有类似getter和setter的东西?

    因为我使用的是Python2.5,所以不能使用Python2.6的getter/setters。

    有什么帮助吗?

    3 回复  |  直到 15 年前
        1
  •  29
  •   Josh    7 年前

    也可以重写setattr和getattr。例如,假设您想将字段标记为脏字段,您可能会遇到如下情况:

    class MyModel:
        _name_dirty = False
    
        name = models.TextField()
    
        def __setattr__(self, attrname, val):
            super(MyModel, self).__setattr__(attrname, val)
    
            self._name_dirty = (attrname == 'name')
    
    
        def __getattr__(self, attrname):
            if attrname == 'name' and self._name_dirty:
                raise('You should get a clean copy or save this object.')
    
            return super(MyModel, self).__getattr__(attrname)
    
        2
  •  8
  •   avelis Michael    7 年前

    pre_save signal handler 到要保存的模型,在值保存到数据库之前更新这些值。

    编辑: 在您的情况下,标准的Python属性可能就是解决这个问题的方法。有一个 long standing ticket 为Django添加适当的getter/setter支持,但这不是一个简单的问题。

    您可以使用中的技术将属性字段添加到管理中 this blog post

        3
  •  5
  •   Justin Alexander    9 年前

    设置属性 这是一个很好的解决方案,只是这可能会导致从DB初始化ORM对象时出现问题。然而,有一个技巧可以绕过这一点,这是普遍的。

    class MyModel(models.Model):
        foo = models.CharField(max_length = 20)
        bar = models.CharField(max_length = 20)
    
        def __setattr__(self, attrname, val):
            setter_func = 'setter_' + attrname
            if attrname in self.__dict__ and callable(getattr(self, setter_func, None)):
                super(MyModel, self).__setattr__(attrname, getattr(self, setter_func)(val))
            else:
                super(MyModel, self).__setattr__(attrname, val)
    
        def setter_foo(self, val):
            return val.upper()
    

    秘密是 属性名在self中。\u dict__ '. 当模型从新的或水化的 __口述__

        4
  •  5
  •   Pavel Vergeev    5 年前

    当我研究这个问题时,我突然想到了解决办法 property 装饰工。

    例如,如果你有

    class MyClass(models.Model):
        my_date = models.DateField()
    

    你可以把它变成

    class MyClass(models.Model):
        _my_date = models.DateField(
            db_column="my_date",  # allows to avoid migrating to a different column
        )
    
        @property
        def my_date(self):
            return self._my_date
    
        @my_date.setter
        def my_date(self, value):
            if value > datetime.date.today():
                logger.warning("The date chosen was in the future.")
            self._my_date = value
    

    https://www.stavros.io/posts/how-replace-django-model-field-property/