1

私はDexterityツールを使用して自分のPloneサイトにコンテンツを作成しようとしていますcreateContentInContainer

zopepyインスタンスで実行されるスクリプトを作成しました。これにより、次のことが実現されます。

  • SQLテーブルからデータを選択します。
  • 製品で定義されたカスタムコンテンツタイプを反映するタプルのリストを作成します。

私は自分のアプローチが非常に素朴であることを知っていますが、次の方法でアプリケーションデータベースへの接続を作成しました。

storage = FileStorage.FileStorage('.../var/filestorage/Data.fs')
db = DB(storage)
conn = db.open()
dbroot = conn.root()

私は次の方法でコンテンツを作成しようとしています:

createContentInContainer(dbroot['Application']['myapp']['existingfolder'], portal_type, checkConstraints=False, content=item)

portal_type以前はカスタムコンテンツタイプに設定されていました。コンテンツのインターフェース( TypeErroritemをスローする)に渡されるタプルのリストと、インターフェースから継承する未登録のアダプターの両方でした。Could not adapt

タイプのインターフェイスはに登録されmysite.Widget.xmlprofiles/defualt/typesいますが、スクリプトは次のようにスローし続けます。

Traceback (most recent call last):
  File "./bin/zopepy", line 345, in <module>
    execfile(__file__)
  File "importdex.py", line 105, in <module>
    createContentInContainer(dbroot['Application']['myapp']['existingfolder'], portal_type, checkConstraints=False, content=item)
  File "env/mysite/eggs/plone.dexterity-1.0-py2.7.egg/plone/dexterity/utils.py", line 149, in createContentInContainer
    content = createContent(portal_type, **kw)
  File "env/mysite/eggs/plone.dexterity-1.0-py2.7.egg/plone/dexterity/utils.py", line 105, in createContent
    fti = getUtility(IDexterityFTI, name=portal_type)
  File "env/mysite/eggs/zope.component-3.9.5-py2.7.egg/zope/component/_api.py", line 169, in getUtility
    raise ComponentLookupError(interface, name)
zope.component.interfaces.ComponentLookupError: (<InterfaceClass plone.dexterity.interfaces.IDexterityFTI>, 'mysite.Widget')

私が言ったように、私は私のアプローチで非常に素朴であることを知っています、そして私はおそらく手で平手打ちするに値します。紛らわしい方法で質問を提示してしまったことをお詫び申し上げます。

私の質問は次のとおりです。

  • createContentInContainerzopepyからインスタンス化できますか?私の不正な接続は十分ですか、それともDexterity / FTIが私が求めていることを達成するために必要なものを継承するために、スクリプトをアプリケーション内で実行する必要がありますか?
  • アダプターが必要ですか?私が持っているものは、インターフェイスを継承し、インターフェイスをとにgrok.Adapter渡しますが、コンテンツスキーマ全体に基づいてプロパティを宣言する必要がありますか?grok.providesgrok.context
  • タプルのリストは任意です。ZODBの構造を考えると、それはやるべきことのように思えました。コンテンツタイプのスキーマを登録済みアダプターのプロパティとして宣言する場合、データはオブジェクト(アダプター)の属性に準拠するように作成する必要がありますよね?
4

1 に答える 1

1

コードを機能させるには、もう少しコンテキストを設定する必要があります。たとえば、Ploneサイトはローカルコンポーネントレジストリとして機能します。

また、コマンドを使用するbin/instance run [scriptname]ことをお勧めします。これにより、データベース接続がセットアップされapp、スクリプトとしてルートオブジェクトが渡されます。そのスクリプトでは、次の定型文を使用して、残りの足場を作成します。

import transaction
from zope.app.component.hooks import setSite
from Testing.makerequest import makerequest
from AccessControl.SecurityManagement import newSecurityManager

plone_site_id = 'Plone' # Adjust as needed.

app = makerequest(app)
site = app[plone_site_id]
setSite(site)
user = app.acl_users.getUser('admin').__of__(site.acl_users)
newSecurityManager(None, user)

これらを配置すると、コードを実行するために必要なすべてのものが揃います。最後に電話することを忘れないでくださいtransaction.commit()。Ploneサイトはローカル変数で到達可能ですsite

于 2012-10-04T12:49:30.757 に答える