.. Basic Layout ================== 基本的なレイアウト ================== .. The starter files generated by the ``alchemy`` scaffold are very basic, but .. they provide a good orientation for the high-level patterns common to most .. :term:`url dispatch` -based :app:`Pyramid` projects. ``alchemy`` scaffold によって生成される初期ファイルは非常に基本的なもの ですが、ほとんどの :term:`url dispatch` ベースの :app:`Pyramid` プロジェクト に共通する高レベルパターンの良い方向性を提供します。 .. The source code for this tutorial stage can be browsed at .. `http://github.com/Pylons/pyramid/tree/1.3-branch/docs/tutorials/wiki2/src/basiclayout/ .. `_. このチュートリアルステージのソースコードを以下の場所で閲覧することができます。 `http://github.com/Pylons/pyramid/tree/1.3-branch/docs/tutorials/wiki2/src/basiclayout/ `_. .. Application Configuration with ``__init__.py`` ``__init__.py`` でのアプリケーション設定 ---------------------------------------------- .. A directory on disk can be turned into a Python :term:`package` by containing .. an ``__init__.py`` file. Even if empty, this marks a directory as a Python .. package. We use ``__init__.py`` both as a marker indicating the directory .. it's contained within is a package, and to contain configuration code. ディスク上のディレクトリは ``__init__.py`` ファイルを含むことによって Python :term:`package` になることができます。このファイルがたとえ空でも、 Python パッケージとしてディレクトリをマークします。私たちはディレクトリ がパッケージであることを示すマーカーとして、および設定コードを置くために ``__init__.py`` を使用します。 .. Open ``tutorial/tutorial/__init__.py``. It should already contain .. the following: ``tutorial/tutorial/__init__.py`` を開いてください。 すでに以下の内容が含まれているはずです: .. literalinclude:: src/basiclayout/tutorial/__init__.py :linenos: :language: py .. Let's go over this piece-by-piece. First, we need some imports to support .. later code: 順番に見て行きましょう。 まず、後のコードのためにいくつかのインポートが必要です: .. literalinclude:: src/basiclayout/tutorial/__init__.py :end-before: main :linenos: :language: py .. ``__init__.py`` defines a function named ``main``. Here is the entirety of .. the ``main`` function we've defined in our ``__init__.py``: ``__init__.py`` は ``main`` という名前の関数を定義しています。 これは ``__init__.py`` の中で定義された ``main`` 関数全体です: .. literalinclude:: src/basiclayout/tutorial/__init__.py :pyobject: main :linenos: :language: py .. When you invoke the ``pserve development.ini`` command, the ``main`` function .. above is executed. It accepts some settings and returns a :term:`WSGI` .. application. (See :ref:`startup_chapter` for more about ``pserve``.) ``pserve development.ini`` コマンドを起動すると、上記の ``main`` 関数が 実行されます。 ``main`` 関数は、いくつかの設定を受け取って :term:`WSGI` アプリケーションを返します (``pserve`` に関する詳細は :ref:`startup_chapter` を参照してください)。 .. The main function first creates a :term:`SQLAlchemy` database engine using .. ``engine_from_config`` from the ``sqlalchemy.`` prefixed settings in the .. ``development.ini`` file's ``[app:main]`` section. This will be a URI .. (something like ``sqlite://``): main 関数は最初に ``engine_from_config`` を使用して ``development.ini`` ファイルの ``[app:main]`` セクション中の ``sqlalchemy.`` 接頭辞のついた 設定から :term:`SQLAlchemy` データベースエンジンを作成します。これは (``sqlite://`` のような) URI になります: .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 13 :language: py .. ``main`` then initializes our SQLAlchemy session object, passing it the .. engine: ``main`` はその後、 engine を渡すことで SQLAlchemy セッションオブジェクト を初期化します: .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 14 :language: py .. ``main`` subsequently initializes our SQLAlchemy declarative ``Base`` object, .. assigning the engine we created to the ``bind`` attribute of it's .. ``metadata`` object. This allows table definitions done imperatively .. (instead of declaratively, via a class statement) to work. We won't use any .. such tables in our application, but if you add one later, long after you've .. forgotten about this tutorial, you won't be left scratching your head when it .. doesn't work. ``main`` は続いて SQLAlchemy の declarative (宣言的) ``Base`` オブジェクトを 初期化します (作成した engine を ``metadata`` オブジェクトの ``bind`` 属性に 割り当てます)。これは、 (クラス構文によって宣言的に行う代わりに) 命令的に 行われたテーブル定義が動作するようにします。このアプリケーションの中では そのようなテーブルを使用しませんが、後で (それもこのチュートリアルのこと なんか忘れてしまうくらいかなり後になって) そのようなテーブルを追加したなら、 それが動作しないことにずっと悩むことになるでしょう。 .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 15 :language: py .. The next step of ``main`` is to construct a :term:`Configurator` object: ``main`` の次のステップは :term:`Configurator` オブジェクトを構築することです: .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 16 :language: py .. ``settings`` is passed to the Configurator as a keyword argument with the .. dictionary values passed as the ``**settings`` argument. This will be a .. dictionary of settings parsed from the ``.ini`` file, which contains .. deployment-related values such as ``pyramid.reload_templates``, .. ``db_string``, etc. ``settings`` は ``**settings`` 引数として渡された辞書の値を持つ キーワード引数として Configurator に渡されます。 これは ``.ini`` ファイルからパースされた設定の辞書になり、これには デプロイ関連の値である ``pyramid.reload_templates`` や ``db_string`` などが含まれます。 .. ``main`` now calls :meth:`pyramid.config.Configurator.add_static_view` with .. two arguments: ``static`` (the name), and ``static`` (the path): ``main`` は 2つの引数、 ``static`` (名前) と ``static`` (パス) を引数と して :meth:`pyramid.config.Configurator.add_static_view` を呼び出します。 .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 17 :language: py .. This registers a static resource view which will match any URL that starts .. with the prefix ``/static`` (by virtue of the first argument to .. ``add_static_view``). This will serve up static resources for us from within .. the ``static`` directory of our ``tutorial`` package, in this case, via .. ``http://localhost:6543/static/`` and below (by virtue of the second argument .. to add_static_view). With this declaration, we're saying that any URL that .. starts with ``/static`` should go to the static view; any remainder of its .. path (e.g. the ``/foo`` in ``/static/foo``) will be used to compose a path to .. a static file resource, such as a CSS file. これは ``/static`` 接頭辞から始まる全ての URL に一致する静的リソースの ビューを登録します (``add_static_view`` への最初の引数によって)。これによって ``tutorial`` パッケージの中の ``static`` ディレクトリにある静的リソースが、 この場合は ``http://localhost:6543/static/`` 以下を経由して返されるように なります (add_static_view への2番目の引数によって)。この宣言によって、 ``/static`` から始まる全ての URL は静的ビューに行かなくてはならない、と いうことを表しています。パスの残りの全ての部分 (例: ``/static/foo`` の ``/foo``) は CSS ファイルなどの静的ファイルリソースへのパスを作成するのに使われます。 .. Using the configurator ``main`` also registers a :term:`route configuration` .. via the :meth:`pyramid.config.Configurator.add_route` method that will be .. used when the URL is ``/``: また、 ``main`` は configurator を使用して URL が ``/`` の場合に使用される :term:`route configuration` を :meth:`pyramid.config.Configurator.add_route` メソッド経由で登録します: .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 18 :language: py .. Since this route has a ``pattern`` equalling ``/`` it is the route that will .. be matched when the URL ``/`` is visited, e.g. ``http://localhost:6543/``. このルートは ``/`` に一致する ``パターン`` を持っているので、 URL ``/`` 、 例えば ``http://localhost:6543/`` を閲覧した場合にマッチします。 .. ``main`` next calls the ``scan`` method of the configurator .. (:meth:`pyramid.config.Configurator.scan`), which will recursively scan our .. ``tutorial`` package, looking for ``@view_config`` (and .. other special) decorators. When it finds a ``@view_config`` decorator, a .. view configuration will be registered, which will allow one of our .. application URLs to be mapped to some code. ``main`` は、次に configurator の ``scan`` メソッド (:meth:`pyramid.config.Configurator.scan`) を呼び出します。 これは ``@view_config`` (また他の特別な) デコレータを探して ``tutorial`` パッケージを再帰的に走査します。 ``@view_config`` デコレータが見つかったら、 ビュー設定が登録されます。それはアプリケーション URL の 1 つをあるコード にマップすることを可能にするでしょう。 .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 19 :language: py .. Finally, ``main`` is finished configuring things, so it uses the .. :meth:`pyramid.config.Configurator.make_wsgi_app` method to return a .. :term:`WSGI` application: 最後に、 ``main`` は設定を終えて、 :meth:`pyramid.config.Configurator.make_wsgi_app` メソッドを使用して :term:`WSGI` アプリケーションを返します。 .. literalinclude:: src/basiclayout/tutorial/__init__.py :lines: 20 :language: py .. View Declarations via ``views.py`` ``views.py`` によるビュー定義 ---------------------------------- .. Mapping a :term:`route` to code that will be executed when a match for .. the route's pattern occurs is done by registering a :term:`view .. configuration`. Our application uses the .. :meth:`pyramid.view.view_config` decorator to map view callables to .. each route, thereby mapping URL patterns to code. :term:`route` からそのルートのパターンが一致する時に実行されるコードへ のマッピングは :term:`view configuration` の登録により行われます。 このアプリケーションでは、各ルートにビュー callable をマッピングするために :meth:`pyramid.view.view_config` デコレータを使用していて、それによって URL パターンをコードにマッピングします。 .. Open ``tutorial/tutorial/views.py``. It should already contain the following: ``tutorial/tutorial/views.py`` を開いてください。 すでに以下の内容が含まれているはずです: .. literalinclude:: src/basiclayout/tutorial/views.py :linenos: :language: py .. The important part here is that the ``@view_config`` decorator associates the .. function it decorates (``my_view``) with a :term:`view configuration`, .. consisting of: ここで重要なのは、 ``@view_config`` デコレータがそれがデコレートする関数 (``my_view``) を以下のような :term:`view configuration` と関連付けるという ことです: .. * a ``route_name`` (``home``) .. * a ``renderer``, which is a template from the ``templates`` subdirectory .. of the package. * ``route_name`` (``home``) * ``renderer`` これはパッケージの ``templates`` サブディレクトリに存 在するテンプレートです。 .. When the pattern associated with the ``home`` view is matched during a request, .. ``my_view()`` will be executed. ``my_view()`` returns a dictionary; the .. renderer will use the ``templates/mytemplate.pt`` template to create a response .. based on the values in the dictionary. ``home`` ビューに関連したパターンがリクエストの間にマッチした場合、 ``my_view()`` が実行されるようになります。 ``my_view()`` は辞書を返します; レンダラーは辞書中の値に基づいてレスポンスを生成するために ``templates/mytemplate.pt`` テンプレートを使用します。 .. Note that ``my_view()`` accepts a single argument named ``request``. This is .. the standard call signature for a Pyramid :term:`view callable`. ``my_view()`` が ``request`` という名前の単一の引数を受け取ることに注意 してください。これは Pyramid :term:`view callable` の標準的な呼び出し シグネチャです。 .. Remember in our ``__init__.py`` when we executed the .. :meth:`pyramid.config.Configurator.scan` method, i.e. ``config.scan()``? The .. purpose of calling the scan method was to find and process this .. ``@view_config`` decorator in order to create a view configuration within our .. application. Without being processed by ``scan``, the decorator effectively .. does nothing. ``@view_config`` is inert without being detected via a .. :term:`scan`. ``__init__.py`` の中で :meth:`pyramid.config.Configurator.scan` メソッド (つまり ``config.scan()``) を実行した時のことを覚えていますか? scan メソッドを呼ぶ目的は、アプリケーション内のビュー設定を生成する ために、この ``@view_config`` デコレータを見つけて処理することでした。 ``scan`` によって処理されなければ、デコレータは実質的に何もしません。 :term:`scan` によって検知されなければ、 ``@view_config`` は不活発です。 .. The sample ``my_view()`` created by the scaffold uses a ``try:`` and ``except:`` .. clause, to detect if there is a problem accessing the project database and .. provide an alternate error response. That response will include the text .. shown at the end of the file, which will be displayed in the browser to .. inform the user about possible actions to take to solve the problem. scaffold によって作成されたサンプルの ``my_view()`` は、 ``try:`` と ``except:`` 節を使用して、プロジェクトデータベースへのアクセスに問題が あるかどうかを検出し、代替エラーレスポンスを提供します。そのレスポンスは、 ファイルの最後に示されたテキストを含み、問題を解決するためにユーザが 取ることのできるアクションについて通知するためブラウザに表示されます。 .. Content Models with ``models.py`` ``models.py`` とコンテンツのモデル -------------------------------------- .. In a SQLAlchemy-based application, a *model* object is an object composed by .. querying the SQL database. The ``models.py`` file is where the ``alchemy`` .. scaffold put the classes that implement our models. SQLAlchemy ベースのアプリケーションの中で、 *model* オブジェクトは SQL データベースに問い合わせることによって構成されるオブジェクトです。 ``alchemy`` scaffold は、モデルを実装するクラスを ``models.py`` ファイルに 出力します。 .. Open ``tutorial/tutorial/models.py``. It should already contain the following: ``tutorial/tutorial/models.py`` を開いてください。 すでに以下の内容が含まれているはずです: .. literalinclude:: src/basiclayout/tutorial/models.py :linenos: :language: py .. Let's examine this in detail. First, we need some imports to support later code: それでは詳しく見てみましょう。最初に、この後のコードを動かすために いくつかのインポートが必要です: .. literalinclude:: src/basiclayout/tutorial/models.py :end-before: DBSession :linenos: :language: py .. Next we set up a SQLAlchemy ``DBSession`` object: 次に SQLAlchemy の ``DBSession`` オブジェクトをセットアップします: .. literalinclude:: src/basiclayout/tutorial/models.py :lines: 16 :language: py .. ``scoped_session`` and ``sessionmaker`` are standard SQLAlchemy helpers. .. ``scoped_session`` allows us to access our database connection globally. .. ``sessionmaker`` creates a database session object. We pass to .. ``sessionmaker`` the ``extension=ZopeTransactionExtension()`` extension .. option in order to allow the system to automatically manage database .. transactions. With ``ZopeTransactionExtension`` activated, our application .. will automatically issue a transaction commit after every request unless an .. exception is raised, in which case the transaction will be aborted. ``scoped_session`` と ``sessionmaker`` は SQLAlchemy の標準的なヘルパー です。 ``scoped_session`` は、データベース接続にグローバルにアクセスできる ようにします。 ``sessionmaker`` はデータベースのセッションオブジェクトを 作成します。システムが自動的にデータベーストランザクションを管理する ことを可能にするために ``sessionmaker`` に ``extension=ZopeTransactionExtension()`` 拡張オプションを渡しています。 ``ZopeTransactionExtension`` を有効にすると、アプリケーションはすべての リクエストの後で自動的にトランザクションのコミットを発行します。ただし、 例外が上げられた場合にはトランザクションは abort します。 .. We also need to create a declarative ``Base`` object to use as a .. base class for our model: また、モデルのベースクラスとして使うために declarative ``Base`` オブジェクトを作成する必要があります: .. literalinclude:: src/basiclayout/tutorial/models.py :lines: 17 :language: py .. Our model classes will inherit from this ``Base`` class so they can be .. associated with our particular database connection. モデルクラスはこの ``Base`` からクラスを継承します。そのため それらを特定のデータベース接続に関連付けることができます。 .. To give a simple example of a model class, we define one named ``MyModel``: モデルクラスの簡単な例のため、 ``MyModel`` という名前のモデルを定義して います。 .. literalinclude:: src/basiclayout/tutorial/models.py :pyobject: MyModel :linenos: :language: py .. Our example model has an ``__init__`` method that takes a two arguments .. (``name``, and ``value``). It stores these values as ``self.name`` and .. ``self.value`` .. within the ``__init__`` function itself. The ``MyModel`` class also has a .. ``__tablename__`` attribute. This informs SQLAlchemy which table to use to .. store the data representing instances of this class. サンプルモデルの ``__init__`` メソッドは 2 つの引数を取ります (``name`` と ``value``)。 これらの値は ``__init__`` 関数自身の中で ``self.name`` および ``self.value`` として保存されます。 ``MyModel`` クラスはまた、 ``__tablename__`` 属性を持っています。これは、このクラスのインスタンス を表すデータを格納するために使用するテーブルを SQLAlchemy に通知します。 .. That's about all there is to it to models, views, and initialization code in .. our stock application. アプリケーションに含まれるモデル、ビュー、および初期化コードに関して、 これでおよそすべてです。