Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 22, 2009 03:44:11

denz
От:
Зарегистрирован: 2007-01-09
Сообщения: 117
Репутация: +  0  -
Профиль   Отправить e-mail  

form.Field MRO

В общем и среднем такой прикол:
имеем стуктуру (описываю
/django_project/forms.py



/django_project/apps/app1/forms.py

/django_project/forms.py

class CountersField(forms.fields.IntegerField):
def clean(self, value):
re_s= re.compile("\d*", re.U)
return super(CountersField, self).clean("".join(re.findall(re_s,value)))
/django_project/apps/app1/forms.py
from django_project.forms import CountersField
class SomeForm(forms.Form):

f1 = forms.ModelChoiceField()

f2 = forms.DateTimeField(initial = datetime.datetime(2008, 12,30))
input = CountersField()
output = CountersField()
а теперь собсно прикол:
при выводе этой формы в шаблоне отображаются только два первых поля.
Кастомное поле не отображается, потому, что
#python manage.py shell
>>> from django import forms
>>> from django_project.apps.app1.forms import SomeForm
>>> f= SomeForm()
>>> f.input
<django_project.forms.CountersField object at 0x120c110>
>>> isinstance(f.input, forms.Field)
False
То есть при инициализации формы джанговским __init__ для форм, это поле не опознается как субкласс Field, и не вытягивет его в dict для Form
От конфигурации строки импорта (from django.forms import Field или from django.forms.fields import Field) - ничего не зависит.
От конфигурации определения (class CountersField(forms.fields.IntegerField) или class CountersField(forms.Field или других комбинаций) - тоже ничего не зависит.
При этом - если встромить определение CountersField в /django_project/apps/app1/forms.py -
все работает нормально.
Может найдутся у когонибудь идеи, оправдывающие такое поведение всеми любимого языка?



Отредактировано (Янв. 22, 2009 03:50:57)

Офлайн

#2 Фев. 1, 2009 22:52:42

denz
От:
Зарегистрирован: 2007-01-09
Сообщения: 117
Репутация: +  0  -
Профиль   Отправить e-mail  

form.Field MRO

lorien
Странно, у меня поля вообще не доступны при прямом обращении (form.foo), тока если (form) и класс у этих полей не forms.Field, а django.forms.forms.BoundField
поля по именам аттрибутов существуют до запуска Form.__init__. Потом они загоняются в словарь. Отбираются по принадлежности к form.Field



Офлайн

#3 Фев. 1, 2009 23:51:33

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

form.Field MRO

denz
Может найдутся у когонибудь идеи, оправдывающие такое поведение всеми любимого языка?
Это особенности системы импорта модулей.

Вообще-то использовать имя пакета проекта при импорте априори плохая идея. Одну из причин вы и обнаружили.



Офлайн

#4 Фев. 2, 2009 13:43:40

denz
От:
Зарегистрирован: 2007-01-09
Сообщения: 117
Репутация: +  0  -
Профиль   Отправить e-mail  

form.Field MRO

Daevaorn
denz
Может найдутся у когонибудь идеи, оправдывающие такое поведение всеми любимого языка?
Это особенности системы импорта модулей.

Вообще-то использовать имя пакета проекта при импорте априори плохая идея. Одну из причин вы и обнаружили.
То есть дело не в MRO а в механизме импорта модулей? Ты что то знаешь, осталось только понять - откуда ты это знаешь :) Ткни ссылку плиз.



Офлайн

#5 Фев. 2, 2009 14:56:08

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

form.Field MRO

lorien
Так у тебя в коде же выполняется __init__. Я про это и написал, что странно, как ты получаешь доступ к этим полям.
У него поля не матчатся как forms.Field, соотвественно из __class__.__dict__ метаклассом не удаляются и доступны далее.

denz
То есть дело не в MRO а в механизме импорта модулей? Ты что то знаешь, осталось только понять - откуда ты это знаешь smile Ткни ссылку плиз.
Если учесть что MRO актуально при иерархии множественного наследования, то тут наследование простое и врядли вызывает сложности.

Дело именно в питонячих импортах. Это некое империческое занание основанное на опыте:-)

Сводится к банальному примеру.Допустим есть пакет:
$ ls -R
.:
foo

./foo:
bar.py __init__.py
и в bar.py есть:
$ cat foo/bar.py

class Bar(object):
pass
и в итоге
$ cd foo
$ python

>>> import sys
>>>
>>> sys.path = [".."] + sys.path
>>>
>>> from bar import Bar
>>> from foo.bar import Bar as Bar1
>>>
>>> Bar == Bar1
False
>>>
>>> b = Bar()
>>> isinstance(b, Bar1)
False
В джанге для моделей это решается сравнением абсолютных путей в ФС модулей: http://code.djangoproject.com/browser/django/trunk/django/db/models/loading.py#L156



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version