Почему Django использует BaseForm? - PullRequest
2 голосов
/ 05 июля 2010

Кажется, я наконец-то понял, что им нужно использовать это DeclarativeFieldsMetaclass (чтобы превратить поля класса в переменные экземпляра и поддерживать их порядок с помощью упорядоченного / отсортированного слова). Тем не менее, я все еще не совсем уверен, почему они решили использовать BaseForm вместо того, чтобы реализовывать все напрямую в классе Form?

Они оставили комментарий ,

class Form(BaseForm):
    "A collection of Fields, plus their associated data."
    # This is a separate class from BaseForm in order to abstract the way
    # self.fields is specified. This class (Form) is the one that does the
    # fancy metaclass stuff purely for the semantic sugar -- it allows one
    # to define a form using declarative syntax.
    # BaseForm itself has no way of designating self.fields.

Но я не очень понимаю это. «Для того, чтобы абстрагировать способ определения self.fields», - но Python вызывает DeclarativeFieldsMetaclass.__new__ до Form.__init__, чтобы они могли в полной мере использовать self.fields внутри Form.__init__ как есть; зачем им нужен дополнительный слой абстракции?

Ответы [ 2 ]

2 голосов
/ 05 июля 2010

Я думаю, что причина проста, т. Е. Только с BaseForm вы не можете определять поля, используя декальтрационный синтаксис, т.е.

class MyForm(Form):
    field_xxx = form.TextField(...)
    field_nnn _ form.IntegerField(...)

Для такой вещи, для работы которой должен быть метакласс DeclarativeFieldsMetaclass, который установлен только в форме, они сделали это, потому что

Это отдельный класс от BaseForm чтобы абстрагировать путь, self.fields указывает

так что теперь вы можете написать класс WierdForm, в котором поля могут быть определены, может быть некоторым странным способом, например. передача параметров в объект класса, точка - это все, что API находится в BaseForm, а класс Form просто предоставляет легко определяемые поля.

Сводка : IMO django предпочел ввести другой уровень, чтобы при необходимости можно было реализовать декларацию полей другого типа, по крайней мере, чтобы отделить неосновную функциональность форм.

0 голосов
/ 05 июля 2010

* Источник: 1002 *

class MetaForm(type):
    def __new__(cls, name, bases, attrs):
        print "%s: %s" % (name, attrs)
        return type.__new__(cls, name, bases, attrs)

class BaseForm(object):
    my_attr = 1
    def __init__(self):
        print "BaseForm.__init__"

class Form(BaseForm):
    __metaclass__ = MetaForm
    def __init__(self):
        print "Form.__init__"

class CustomForm(Form):
    my_field = 2
    def __init__(self):
        print "CustomForm.__init__"

f = CustomForm()

Выход:

Form: {'__module__': '__main__', '__metaclass__': <class '__main__.MetaForm'>, '__init__':<function __init__ at 0x0227E0F0>}
CustomForm: {'__module__': '__main__', 'my_field': 2, '__init__': <function __init__ at 0x0227E170>}
CustomForm.__init__

Похоже, MetaForm.__new__ вызывается дважды. Один раз для Form и один раз для CustomForm, но никогда для BaseForm. Имея чистый (пустой) класс Form, не будет никаких посторонних атрибутов для зацикливания. Это также означает, что вы можете определить Fields внутри BaseForm, который можно использовать для внутреннего использования, но избегайте рендеринга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...