summaryrefslogtreecommitdiff
path: root/docs/tutorials/wiki2/basiclayout.rst
blob: 17dcfc48f2da4e7b8827cd6b63476f96da2aed04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
============
Basic Layout
============

The starter files generated by the ``pyramid_routesalchemy`` template
are basic, but they provide a good orientation for the high-level
patterns common to most :term:`url dispatch` -based :app:`Pyramid`
projects.

The source code for this tutorial stage can be browsed at
`http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/src/basiclayout/
<http://github.com/Pylons/pyramid/tree/master/docs/tutorials/wiki2/src/basiclayout/>`_.

App Startup with ``__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 package marker and to contain
configuration code.

The generated ``development.ini`` file is read by ``paster`` which looks for
the application module in the ``use`` variable of the ``app:tutorial``
section. The *entry point* is defined in the Setuptools configuration of this
module, specifically in the ``setup.py`` file. For this tutorial, the *entry
point* is defined as ``tutorial:main`` and points to the following ``main``
function:

   .. literalinclude:: src/basiclayout/tutorial/__init__.py
      :linenos:
      :language: py

#. *Lines 1-4*. Imports to support later code.

#. *Line 9*. Create a SQLAlchemy database engine from the ``sqlalchemy.``
   prefixed settings in the ``development.ini`` file's ``[app:tutorial]``
   section.  This will be a URI (something like ``sqlite://``).

#. *Line 10*. We initialize our SQL database using SQLAlchemy, passing
   it the engine

#. *Line 11*.  We construct a :term:`Configurator`.  ``settings`` is
   passed as a keyword argument with the dictionary values passed by
   PasteDeploy as the ``settings`` argument.  This will be a
   dictionary of settings parsed by PasteDeploy, which contains
   deployment-related values such as ``reload_templates``,
   ``db_string``, etc.

#. *Line 12*.  We call
   :meth:`pyramid.config.Configurator.add_static_view` with the
   arguments ``static`` (the name), and ``tutorial:static`` (the path).  This
   registers a static resource view which will match any URL that starts with
   ``/static/``.  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.  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.

#. *Lines 13-14*.  Register a :term:`route configuration` via the
   :meth:`pyramid.config.Configurator.add_route` method that will be
   used when the URL is ``/``.  Since this route has a ``pattern`` equalling
   ``/`` it is the "default" route. The argument named ``view`` with the
   value ``tutorial.views.my_view`` is the dotted name to a *function* we
   write (generated by the ``pyramid_routesalchemy`` template) that is given
   a ``request`` object and which returns a response or a dictionary.  You
   will use :meth:`pyramid.config.Configurator.add_route` statements
   in a :term:`URL dispatch` based application to map URLs to code.  This
   route also names a ``view_renderer``, which is a template which lives in
   the ``templates`` subdirectory of the package.  When the
   ``tutorial.views.my_view`` view returns a dictionary, a :term:`renderer`
   will use this template to create a response.

#. *Line 15*.  We use the
   :meth:`pyramid.config.Configurator.make_wsgi_app` method to return
   a :term:`WSGI` application.

Content Models with ``models.py``
---------------------------------

In a SQLAlchemy-based application, a *model* object is an object
composed by querying the SQL database which backs an application.
SQLAlchemy is an "object relational mapper" (an ORM).  The
``models.py`` file is where the ``pyramid_routesalchemy`` Paster
template put the classes that implement our models.

Here is the source for ``models.py``:

   .. literalinclude:: src/basiclayout/tutorial/models.py
      :linenos:
      :language: py

#. *Lines 1-13*.  Imports to support later code.

#. *Line 15*.  We set up a SQLAlchemy "DBSession" object here.  We
   specify that we'd like to use the "ZopeTransactionExtension".  This
   extension is an extension which allows us to use a *transaction
   manager* instead of controlling commits and aborts to database
   operations by hand.

#. *Line 16*.  We create a declarative ``Base`` object to use as a
   base class for our model.

#. *Lines 18-26*.  A model class named ``MyModel``.  It has an
   ``__init__`` 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.

#. *Lines 28-33*.  A function named ``populate`` which adds a single
   model instance into our SQL storage and commits a transaction.

#. *Lines 35-42*.  A function named ``initialize_sql`` which receives a SQL
   database engine and binds it to our SQLAlchemy DBSession object.  It also
   calls the ``populate`` function, to do initial database population.