10

我想向 Django 模型的实例添加自定义属性。这些属性不应存储在数据库中。在任何其他类中,属性将简单地由__init__方法初始化。

我已经看到了三种不同的方法,但没有一种是完全令人满意的。我想知道是否有更好/更多的 pythonic/djangoist 方式来做到这一点?

  1. 覆盖__init__方法:语法有点复杂,但它有效。

    from django.db.models import Model
    
    class Foo(Model):
      def __init__(self, *args, **kwargs):
         super(Model, self).__init__(*args, **kwargs)
         self.bar = 1
    
  2. 使用 Djangopost_init信号:这需要类定义之外的类代码,这不是很可读。

    from django.dispatch import receiver
    from django.db.models.signals import post_init
    @receiver(post_init, sender=Foo)
        def user_init(sender, instance, *args, **kwargs):
          instance.bar = 1
    
  3. 使用实例方法而不是属性:将一般异常作为默认行为引发有点令人不安。

    class Foo(Model):
      def bar(self):
        try:
          return self.bar
        except:
          self.bar = 1
        return self.bar
    

在这三个选择中,第一个对我来说似乎是最糟糕的。你怎么看?有什么选择吗?

4

2 回答 2

9

我会使用 python 中可用的属性装饰器

class Foo(Model):
    @property
    def bar(self):
        if not hasattr(self, '_bar'):
            self._bar = 1

        return self._bar

然后您可以像访问属性一样访问它,而不是使用 () 调用函数

您甚至可以通过内置后备而不是存储来更直接地使用它

class Foo(Model):
    @property
    def bar(self):
        return getattr(self, '_bar', 1)
于 2013-01-22T16:37:44.633 回答
3

覆盖__init__是正确的方法。

于 2013-01-22T18:05:29.460 回答