Django CBV继承:覆盖属性

时间:2012-02-29 18:52:15

标签: python django inheritance django-class-based-views

我正在为Django项目创建基于自定义类的视图,并面临有关属性的设计决策。

Getter功能

我查看了Django的通用视图,发现有很多类提供了类变量以及自定义getter函数。 e.g

class FormMixin(object):
    initial = {}
    def get_initial(self):
        return self.initial

这个设计决定是有道理的,因为这样,你可以在扩展类的重写方法中调用super()

属性

在我的项目中,有些值我有时可以使用简单值覆盖,但有时必须以dnyamically生成。起初我创建了类似于上面的方法,但后来认为可能属性是更好的方法。

class MyBaseView(OtherView):
    counter = None

class MyExtendingView(MyBaseView):
    counter = 5

class MyOtherExtendingView(MyBaseView):
    @property
    def counter(self):
        return self.other_function()

实例.__字典__

我打算在模板中使用这些值。我将扩展视图的实例传递给模板,并按以下方式显示属性:

context['class_instances'] = [MyExtendingView(), MyOtherExtendingView()]

{% for instance in class_instances %}
    {{ instance.counter|default:'' }}
{% endfor %}

现在因为这是一个模板,并且实例属性是值还是函数并不重要,我也可以像这样编写我的类:

class MyExtendingView(MyBaseView):
    counter = 5

class MyOtherExtendingView(MyBaseView):
    def counter(self):
        return self.other_function()

def counter将替换instance.__dict__中旧的基于值的属性。

问题

要回答这个问题,列出哪种方法是最佳选择?

  • getter方法很好,因为它允许super() - 调用父级的getter函数,但在我的大多数情况下可能永远不需要。
  • 属性方法更简单,并且可以编写更少的代码。我不能super() - 调用父母的财产功能。在大多数情况下我不需要这种行为,但可能会出现需要super()功能的情况,因此可以使用属性和自定义getter函数覆盖简单属性的混合。
  • 最后一种方法是比财产方法更少的代码,但我怀疑这是好的风格。

1 个答案:

答案 0 :(得分:2)

  

属性方法更简单,并且编写的代码更少。我不能超级() - 调用父的属性函数。

您实际上可以通过super()访问父级属性:

class A(object):
    @property
    def prop(self):
        return 'A.prop'

class B(A):
    @property
    def prop(self):
        return '%s - %s' % (super(B, self).prop, 'B.prop')

>>> b = B()
>>> b.prop
'A.prop - B.prop'