summaryrefslogtreecommitdiff
path: root/docs/tutorials/wiki2/basiclayout.rst
blob: 7448563c73438c41256103394e18047cc2a0b292 (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
119
120
121
122
123
124
125
126
127
128
129
130
131
============
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 :mod:`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.

When you run the application using the ``paster`` command using the
``development.ini`` generated config file, the application configuration
points at an Setuptools *entry point* described as ``egg:tutorial#app``.  In
our application, because the application's ``setup.py`` file says so, this
entry point happens to be the ``app`` function within the file named
``__init__.py``:

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

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

#. *Lines 12-14*. Get the database configuration string from the
   ``development.ini`` file's ``[app:sqlalchemy]`` section.  This will be a
   URI (something like ``sqlite://``).

#. *Line 15*. Get the database echo setting from ``development.ini``
   file's ``[app:sqlalchemy]`` section.  This will either be ``true``
   or ``false``.  If ``true``, the application will print SQL to the
   console as it is generated and run by SQLAlchemy.  By default, it
   is false.

#. Line *16*. We initialize our SQL database using SQLAlchemy, passing
   it the db string and a variant of the db_echo value.

#. *Line 17*.  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 18*.  We call :meth:`pyramid.configuration.Configurator.begin` which
    tells the configuration machinery we are starting configuration.

#. *Line 19*.  We call
   :meth:`pyramid.configuration.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 20-21*.  Register a :term:`route configuration` via the
   :meth:`pyramid.configuration.Configurator.add_route` method that will be
   used when the URL is ``/``.  Since this route has an ``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.configuration.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 22*.  We call :meth:`pyramid.configuration.Configurator.end` which
    tells the configuration machinery we are ending configuration.

#. *Line 23*.  We use the
   :meth:`pyramid.configuration.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-14*.  Imports to support later code.

#. *Line 16*.  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 17*.  We create a declarative ``Base`` object to use as a
   base class for our model.

#. *Lines 19-27*.  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 29-34*.  A function named ``populate`` which adds a single
   model instance into our SQL storage and commits a transaction.

#. *Lines 36-44*.  A function named ``initialize_sql`` which sets up
   an actual SQL database and binds it to our SQLAlchemy DBSession
   object.  It also calls the ``populate`` function, to do initial
   database population.