Форум сайта python.su
Есть задача, которая будет развивться и дальше. Расчитываю на этой простой задаче “подрасти” и уже дальше двигаться… Задача такая : публикация данных по услугам абонента (жильца). Т.е. абоненту оказываются услуги (Например, домофон, телевидение, Интернет и пр.) , есть система учета платежей (уже давно работает), данные храняться в PostgreSQL в кодировке cp1251. Суть такая : начальная форма запроса содержит поля ввода - название улицы (список улиц), номер дома, квартиры, номер лицевого счета. Т.к. вариантов предоставляемой информации для абонента много, т.е. нет возможность отобразить все в одной или нескольких таблицах - информация по видам оказываемых услуг, платежам, дополнительной информации Эту слабо структурированную информацию хотелось бы получать с PostgreSQL (после запроса) в виде xml данных, затем с помощью xslt преобразовать в html с “динамическим каталогом”.
Первоначально начал смотреть примеры и на основании примеров делать похожее.
Но так ни один пример не заработал… видимо делаю не совсем понимая.
Последний пример сделал следующим образом (уже много чего наменял - возможно уже совсем неправильно):
### interfaces.py ####
import zope.interface
import re
from zope.schema import Text, TextLine
class IAbonentData(zope.interface.Interface):
ul = TextLine(title=(u"Улица"))
dom = TextLine(title=(u"Дом"))
kv = TextLine(title=(u"Квартира"))
ls = TextLine(title=(u"Лицевой счет"))
def name():
""" дплдеплпрлд
оаоароапоарпо
"""
### GetAbonentData.py ####
coding:utf-8
import psycopg
import zope
from abonent.interfaces import IAbonentData
class GetAbonent(persistent.interfaces.IPersistent):
zope.interface.implements(IAbonentData)
def __init__(self, ul='', dom='', kv='', ls=''):
self.ul = ul
self.dom = dom
self.kv = kv
self.ls = ls
def name(self):pass
Отредактировано (Март 19, 2008 11:26:34)
Офлайн
astoonУ меня эти ссылки не работают.
http://localhost:8080/++apidoc++/Code/zope/interface/README.ru.txt (ru)
http://localhost:8080/++apidoc++/Code/zope/interface/human.ru.txt (ru)
http://localhost:8080/++apidoc++/Code/zope/interface/adapter.ru.txt (ru)
Офлайн
Интерфейс у тебя рабочий.
А вот сам класс ты наследуешь тоже от интерфейса (IPersistent) :(
Нужно:
class MyInterface(Interface):
ля ля ля
class MyClass(Persistent):
implements(MyInterface)
Про interface на русском здесь:
http://hlabs.spb.ru/development/zope
Про виды:
<browser:getform - нет такой директивы. См http://localhost:8080/++apidoc++ ZCML reference. Там все директивы разложены по полкам.
Т.е. вместо browser:getform - ставишь browser:page
В zope есть готовое решение для “добавления” объектов: zope.formlib.form.AddForm
Что бы его использовать можно тупо в zcml написать <browser:addform ля ля ля. Правда тогда поглумиться над видом тебе не дадут.
Если ты хочешь эту форму разукрасить рюшечками, тогда пишешь <browser:page ля ля class = .MyClassAddForm, где class MyClassAddForm(AddForm). А с этим классом уже вытворять всякие штуки.
Ты можешь указать свой abonent.pt при добавлении объекта, но опять же без replace context/чего-то там.
AddForm сам заполнит слот body. Все что нужно - это смотреть и восторгаться.
На первый взгляд это может показаться overenginered, но на самом деле это здоровенные такие ходули, которые позволяют перешагивать и через zodb и через генерацию html. Ты просто “даешь ему” свой interface а “он” тебе для него делает форму абстрагируя весь механизм.
Офлайн
vak$ZOPEINSTANCE/etc/zope.conf - devmode on
astoon написал:
http://localhost:8080/++apidoc++/Code/z … DME.ru.txt (ru)
http://localhost:8080/++apidoc++/Code/z … man.ru.txt (ru)
http://localhost:8080/++apidoc++/Code/z … ter.ru.txt (ru)
У меня эти ссылки не работают.
Отредактировано (Март 19, 2008 13:36:35)
Офлайн
astoonНужен какой-то текст, в котором смысл интерфейсов объяснялся бы на пальцах. Перевод основной документации - это хорошо, только писали ее зубры, далекие от проблем неофита. Я в интерфейсы врубал пол года, пока не пришла книжка wcdwz3. А когда пришла - еще полгода :( И до сих пор нет уверенности, что компонентная архитектура это то, что я “знаю и понимаю”.
И про суть интерфейсов станет понятно.
Офлайн
tretiy3Да уж. Никому по-моему еще не удавалось разжевать все просто и быстро на начальном уровне.astoonНужен какой-то текст, в котором смысл интерфейсов объяснялся бы на пальцах. Перевод основной документации - это хорошо, только писали ее зубры, далекие от проблем неофита. Я в интерфейсы врубал пол года, пока не пришла книжка wcdwz3. А когда пришла - еще полгода :( И до сих пор нет уверенности, что компонентная архитектура это то, что я “знаю и понимаю”.
И про суть интерфейсов станет понятно.
Для того чтоб пользовать zope по настоящему, нужно хорошее ООП (с Гаммой, там, Фаулером, и т.п.). Когда человек хватает его, чтоб быстренько накидать сайт, его просто смывает лавиной новых понятий и концепций. Поэтому люди разворачиваются и уходят в пхп и прочую лабуду :(
Отредактировано (Апрель 7, 2008 00:21:23)
Офлайн
Теперь один из практических выводов предыдущего поста: все - компоненты. Или адаптеры, или утилиты - одно из двух. Любая компонента может быть просто вызываемым питон-кодом, никак не связанным с сервером приложений Zope и вообще ни с чем остальным. Она “не знает” о других частях системы ничего.
Для примера - возмем адаптер вида. В других фремворках (например возьмем лучший - Django :) ) - для того чтобы написать класс Вида, нужно его унаследовать от базового класса Вида. Для того чтобы что-то внутри него сделать - тоже много чего нужно наследовать.
В Zope3 изначально ничего наследовать не нужно. Адаптер вида (по аналогии в классом View в Django) - может быть просто обычным Python-классом. Только нужно соблюсти немного условий - в данном случае - он адаптирует контекст и запрос (как мультиадаптер), поэтому должен иметь аргументы в def __init__(контекст, запрос). А наследовать его ни от чего не нужно.
Адаптером вида этот класс становится тоьлко когда ты его регистрируешь в реестре как адаптер определенного интерфейса к определенному интерфейсу запроса (скин, layer). Для удобства и сокращения работы вместо директивы <zope:adapter …> для него введена специальная директива - <browser:page … >
Так можно сказать про другие компоненты. А наследование от всяких полезных классов применяется для того, чтобы сократить объем кода (по крайней мере надо так к этому относиться)
Все это конечно дикое упрощение, но для понимания назначения SiteManager, думаю, сойдет. Дальше нужно почитать про адаптеры последние туторы в топике с документацией в этом разделе форума. И обратить внимание на взаимодействие интерфейсов и адаптеров, как интерфейс “берет” объект и при чем здесь адаптер.
Отредактировано (Март 21, 2008 03:27:57)
Офлайн
Всем спасибо за помощь.
Офлайн
Не получается.
Уже и перечитал все выше написанное несколько раз … и оставлял в покое…
Не получается без ошибок запустить пример…
Видимо просто начальный период нужно пережить.
Подскажите плиз, где может быть ошибка:
<configure
xmlns="http://namespaces.zope.org/zope“
xmlns:browser=”http://namespaces.zope.org/browser“
xmlns:i18n=”http://namespaces.zope.org/i18n“
i18n_domain=”GetAbonentData“
>
<content class=”.GetAbonentData.GetAbonent“>
<implements interface=”zope.app.annotation.IAttributeAnnotatable“>
<require permission=”zope.View“ interface=”.interfaces.IAbonentData“ />
<require permission=”zope.ManageContent“ set_schema=”.interfaces.IAbonentData“ />
</content>
<browser:addMenuItem
class=”.GetAbonentData.AbonentData“
title=”GetAbonentXMLData“
permission=”zope.ManageContent“
view=”Abonent.html“
/>
<browser:addform
schema=”.interfaces.IAbonentData“
label=”kdfjdkfjjfgkjkgj“
content_factory=”.GetAbonentData.GetAbonent“
arguments=”ul dom kv ls“
name=”Abonent.html“
permission=”zope.ManageContent“
/>
<include package=”.browser" />
</configure>
Офлайн
Директива контент устарела. Используй class.
<class class=“.GetAbonentData.GetAbonent”>
<implements
interface=zope.annotation.interfaces.IAttributeAnnotatable“
/>
<factory
id=”.GetAbonentData.GetAbonent“
description=”Ля ля ля“
/>
<require
permission=”zope.View“”
interface=“.interfaces.IAbonentData”/>
<require
permission=“zope.ManageContent”
set_schema=“.interfaces.IAbonentData/>
</class>
Чтобы показать, что это контент, а не что-то там, хватаешь интерфейс этого класса, и явно прописываешь его как content:
<interface
interface=”.interfaces.IAbonentData“
type=”zope.app.content.interfaces.IContentType“
/>
Так надежнее.
Ошибка у тебя здесь:
<browser:addMenuItem
class=”.GetAbonentData.AbonentData“ ??????????????????????????????????
title=”GetAbonentXMLData“
permission=”zope.ManageContent“
view=”Abonent.html“
/>
<browser:addform
schema=”.interfaces.IAbonentData“
label=”kdfjdkfjjfgkjkgj“
content_factory=”.GetAbonentData.GetAbonent“ ??????????????????????????????
arguments=”ul dom kv ls“
name=”Abonent.html“
permission=”zope.ManageContent"
/>
в addMenuItem поддиректива class - это конструктор твоего объекта.
в addForm в поддирективе content_factory должен торчать тот же самый класс.
Офлайн