Django CBV наследование: переопределение атрибутов - PullRequest
1 голос
/ 29 февраля 2012

Я создаю пользовательские представления на основе классов для проекта Django и столкнулся с дизайнерским решением относительно атрибутов.

Функции геттера

Я посмотрел на общие представления Django и увидел, что существует довольно много классов, которые предоставляют как переменные класса, так и пользовательские функции получения. * 1006 например *.

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

Это конструктивное решение имеет смысл, потому что таким образом вы можете вызвать super() в переопределяющем методе расширяющего класса.

Свойства

В моем проекте есть определенные значения, которые я иногда мог бы переопределить, используя простое значение, но иногда они должны создаваться динамически. Сначала я создал методы, аналогичные описанным выше, но потом подумал, что, возможно, свойства - лучший способ сделать это.

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() вызывать функцию get родителя, но в большинстве моих случаев это, вероятно, никогда не понадобится.
  • Подход, основанный на свойствах, намного проще и требует меньше кода для написания. Я не могу super() -созвать функцию свойства родителя, хотя. Мне не понадобится такое поведение в большинстве случаев, но могут быть случаи, когда мне нужна функциональность super(), поэтому будет набор простых атрибутов, которые можно переопределить с помощью свойств и пользовательских функций получения.
  • Последний подход еще меньше кода, чем подход с использованием свойств, но я сомневаюсь, что это хороший стиль.

1 Ответ

2 голосов
/ 01 марта 2012

Подход с использованием свойств намного проще и требует меньше кода для написания. Я не могу super () - вызвать функцию свойства родителя, хотя.

Вы можете получить доступ к родительским свойствам через 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'
...