Differences between revisions 1 and 11 (spanning 10 versions)
Revision 1 as of 2013-08-13 04:11:05
Size: 909
Comment:
Revision 11 as of 2013-08-15 05:12:11
Size: 7778
Comment:
Deletions are marked like this. Additions are marked like this.
Line 3: Line 3:

== Pyramid Setup ==
= Pyramid for Enterprise =

== Install Pyramid ==
Line 15: Line 16:
== Pyramid Project: myapp == == Create Pyramid Project: myapp ==
Line 27: Line 28:
Checking the first version into revision control of your choosing.
Line 47: Line 49:
Replace myapp with your app name.  Replace myapp with your app name.
Line 60: Line 62:
== Write your application == == Build application structure ==

=== Enable Mako ===
In order to use Mako as in Pylons, you must specify a template search path in the settings. Edit development.ini:
{{{
[app:main]
...
mako.directories = myapp:templates
}}}

[[http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/templates.html#mako-templates|enable mako with pyramid]]
[[http://docs.pylonsproject.org/projects/pyramid_cookbook/en/latest/pylons/templates.html|enable mako html with pyramid]]

Then in \__init\__.py add below. This will be needed so that designer can use .html mako template files in his software.
{{{
config = Configurator(settings=settings)
config.add_renderer(".html", "pyramid.mako_templating.renderer_factory")
}}}

=== Add first page ===

We will add new route in. This what tells pyramid program we want localhost/recall
{{{
vi __init__.py
#Add below home
}}}
Add below home
{{{
config.add_route('recall', '/recall')
}}}
Edit views.py and add our new page. This tells that anybody that calls localhost/recall should call our route_name called recall in views.py
{{{
@view_config(route_name='recall', renderer='recall.html')
def recall(request):
    return {'project':'Myapp'}
}}}
Now inside template folder add your new template
{{{
cd template
vi recall.html
}}}
Add
{{{
<html>
 <head>
     <title>${project} Application</title>
 </head>
   <body>
      <h1 class="title">Welcome to <code>${project}</code>, an
       application generated by the <a
       href="http://docs.pylonsproject.org/projects/pyramid/current/"
      >pyramid</a> web application framework using Mako.</h1>
   </body>
 </html>
}}}
Visit: http://localhost:6543/recall

{{attachment:pyramid_mako.png}}

=== Load mysql-python ===
First we need to add required package called "mysql-python". Add this to setup.py under required
{{{
'mysql-python',
}}}
Then do
{{{
python setup.py develop
}}}
This will install required software.

=== Autoload table from database ===
First we need to specify how to connect to database. In development.ini comment out the sqlite and add

{{{
#sqlalchemy.url = sqlite:///%(here)s/lm.sqlite
sqlalchemy.url=mysql://usernamehere:secretpassword@localhost/mydatabase_name?charset=utf8
}}}
'''?charset=utf8''' is optional.

In models.py add below. This creates a python class called Recall and will autoload table called "recall_db" from the database. We use DeferredReflection because this is a helper function from sqlalchemy which does not require "engine" be to bound and loaded at this time. Allows to keep the model/database code in models.py for clean viewing.

{{{
from sqlalchemy.ext.declarative import DeferredReflection

class Recall(DeferredReflection, Base):
    __tablename__ = 'recall_db'
}}}

Now right below '''Base.metadata.bind = engine''' please add
{{{
DeferredReflection.prepare(engine)
}}}
This will load the function and autoload the table that we have defined in the models.py

=== adding url structure /path/bar/foo ===
My application requires that user accesses the site with url like

{{{
http://example.com/recall
http://example.com/recall/2005
http://example.com/recall/2005/Ford
http://example.com/recall/2005/Ford/Mustand
}}}

In order to achieve that we will add these lines of code in __init__.py
{{{
config.add_route('recall', '/recall')
config.add_route('recall_year', '/recall/{year}')
config.add_route('recall_make', '/recall/{year}/{make}')
config.add_route('recall_model', '/recall/{year}/{make}/{model}')
}}}
The /recall/{year} says user will access the address like http://example.com/recall/1999 where 1999 will become a variable year=1999 and will be sent to view with a name of '''recall_year'''

Now lets add the 3 new views in views.py
{{{
@view_config(route_name='recall_year', renderer='recall.html')
def recall_year(request):
    return {'project':'Myapp_year'}

@view_config(route_name='recall_make', renderer='recall.html')
def recall_make(request):
    return {'project':'Myapp_make'}

@view_config(route_name='recall_model', renderer='recall.html')
def recall_model(request):
    return {'project':'Myapp_model'}
}}}

Now we have used pyramid to "build url structure", autoload mysql table, and defined how our app will flow. Now lets load data, send what we want to template and display in our .html template before graphics person makes it pretty.

== DBSession.query, mako and .html templates ==

=== DBSession.query ===
Since we have already defined the database, and autoloaded the table with pyramid lets import it, query it
in views.py

Import Recall, and additional sqlalchemy functions
{{{
from .models import (
    DBSession,
    MyModel,
    Recall,
    )
from sqlalchemy import and_, desc
}}}

Query It
{{{
@view_config(route_name='recall', renderer='recall.html')
def recall(request):
    years=DBSession.query(Recall.YEARTXT).group_by(desc(Recall.YEARTXT))
    return {'project':'Recall','years':years}
}}}

Template [[http://docs.pylonsproject.org/projects/pyramid_tutorials/en/latest/single_file_tasks/single_file_tasks.html#list-mako| for look in mako]], [[http://docs.makotemplates.org/en/latest/runtime.html#the-loop-context|mako loop context]]

vi templates/recall.html and inside body add
{{{
<ul id="years">
% if years:
Click on Year of the vehicle:
  % for year in years:
  <li>
    <span class="actions">
       <a href="${request.route_url('recall_year', year=year[0])}">${year[0]}</a>
    </span>
  </li>
  % endfor
% endif
</ul>
}}}

{{attachment:pyramid_mako_forloop_list.png}}

Because the return value in my case is list (u'2005'), I'm doing year[0] to return u'2005'.

The ${request.route_url('recall_year', year=year[0]) tells system to provide a link to route name in views.py called recall_year and pass parameter year with value of year[0]

=== query with the parameter passed via url ===

Now lets move on to recall_make, do the query for make based on year passed in request

Edit views.py

{{{
@view_config(route_name='recall_year', renderer='recall.html')
def recall_year(request):
    makes=DBSession.query(Recall.MAKETXT).filter(Recall.YEARTXT==request.matchdict['year']).group_by(Recall.MAKETXT)
    return {'project':'Myapp_year','cyear':request.matchdict['year'],'makes':makes}
}}}

 *cyear will be used for "You are browsing XXXX year"
 *makes is the query that lists all makes based on the year supplied

Edit recall.html

{{{
<ul id="makes">
% if makes:
Click on Make of the vehicle:
  % for make in makes:
  <li>
    <span class="actions">
       <a href="${request.route_url('recall_make', year=cyear,make=make[0])}">${make[0]}</a>
    </span>
  </li>
  % endfor
% endif
</ul>
}}}

Pyramid/enterprise

Pyramid for Enterprise

Install Pyramid

aptitude install python-virtualenv

virtualenv --no-site-packages pyramid_env
cd pyramid_env
source ./bin/activate
easy_install pyramid

Create Pyramid Project: myapp

pcreate -s alchemy myapp

Install remaining components

cd myapp
python setup.py develop

[Optional] Checking the first version into revision control of your choosing.

aptitude install bzr
cd myapp
bzr init .
bzr add
bzr commit -m"Initial Import"

Run a test

python setup.py test -q

Check how much code is covered by tests

easy_install nose coverage
nosetests --cover-package=myapp --cover-erase --with-coverage

Populate the database

Replace myapp with your app name.

initialize_myapp_db development.ini

Start the Application

pserve development.ini --reload

Visit http://localhost:6543/

Build application structure

Enable Mako

In order to use Mako as in Pylons, you must specify a template search path in the settings. Edit development.ini:

[app:main]
...
mako.directories = myapp:templates

enable mako with pyramid enable mako html with pyramid

Then in \init\.py add below. This will be needed so that designer can use .html mako template files in his software.

config = Configurator(settings=settings)
config.add_renderer(".html", "pyramid.mako_templating.renderer_factory")

Add first page

We will add new route in. This what tells pyramid program we want localhost/recall

vi __init__.py
#Add below home

Add below home

config.add_route('recall', '/recall')

Edit views.py and add our new page. This tells that anybody that calls localhost/recall should call our route_name called recall in views.py

@view_config(route_name='recall', renderer='recall.html')
def recall(request):
    return {'project':'Myapp'}

Now inside template folder add your new template

cd template
vi recall.html

Add

<html>
 <head>
     <title>${project} Application</title>
 </head>
   <body>
      <h1 class="title">Welcome to <code>${project}</code>, an
       application generated by the <a
       href="http://docs.pylonsproject.org/projects/pyramid/current/"
      >pyramid</a> web application framework using Mako.</h1>
   </body>
 </html>

Visit: http://localhost:6543/recall

pyramid_mako.png

Load mysql-python

First we need to add required package called "mysql-python". Add this to setup.py under required

'mysql-python',

Then do

python setup.py develop

This will install required software.

Autoload table from database

First we need to specify how to connect to database. In development.ini comment out the sqlite and add

#sqlalchemy.url = sqlite:///%(here)s/lm.sqlite
sqlalchemy.url=mysql://usernamehere:secretpassword@localhost/mydatabase_name?charset=utf8

?charset=utf8 is optional.

In models.py add below. This creates a python class called Recall and will autoload table called "recall_db" from the database. We use DeferredReflection because this is a helper function from sqlalchemy which does not require "engine" be to bound and loaded at this time. Allows to keep the model/database code in models.py for clean viewing.

from sqlalchemy.ext.declarative import DeferredReflection

class Recall(DeferredReflection, Base):
    __tablename__ = 'recall_db'

Now right below Base.metadata.bind = engine please add

DeferredReflection.prepare(engine)

This will load the function and autoload the table that we have defined in the models.py

adding url structure /path/bar/foo

My application requires that user accesses the site with url like

http://example.com/recall
http://example.com/recall/2005
http://example.com/recall/2005/Ford
http://example.com/recall/2005/Ford/Mustand

In order to achieve that we will add these lines of code in init.py

config.add_route('recall', '/recall')
config.add_route('recall_year', '/recall/{year}')
config.add_route('recall_make', '/recall/{year}/{make}')
config.add_route('recall_model', '/recall/{year}/{make}/{model}')

The /recall/{year} says user will access the address like http://example.com/recall/1999 where 1999 will become a variable year=1999 and will be sent to view with a name of recall_year

Now lets add the 3 new views in views.py

@view_config(route_name='recall_year', renderer='recall.html')
def recall_year(request):
    return {'project':'Myapp_year'}

@view_config(route_name='recall_make', renderer='recall.html')
def recall_make(request):
    return {'project':'Myapp_make'}

@view_config(route_name='recall_model', renderer='recall.html')
def recall_model(request):
    return {'project':'Myapp_model'}

Now we have used pyramid to "build url structure", autoload mysql table, and defined how our app will flow. Now lets load data, send what we want to template and display in our .html template before graphics person makes it pretty.

DBSession.query, mako and .html templates

DBSession.query

Since we have already defined the database, and autoloaded the table with pyramid lets import it, query it in views.py

Import Recall, and additional sqlalchemy functions

from .models import (
    DBSession,
    MyModel,
    Recall,
    )
from sqlalchemy import and_, desc

Query It

@view_config(route_name='recall', renderer='recall.html')
def recall(request):
    years=DBSession.query(Recall.YEARTXT).group_by(desc(Recall.YEARTXT))
    return {'project':'Recall','years':years}

Template for look in mako, mako loop context

vi templates/recall.html and inside body add

<ul id="years">
% if years:
Click on Year of the vehicle:
  % for year in years:
  <li>
    <span class="actions">
       <a href="${request.route_url('recall_year', year=year[0])}">${year[0]}</a>
    </span>
  </li>
  % endfor
% endif
</ul>

pyramid_mako_forloop_list.png

Because the return value in my case is list (u'2005'), I'm doing year[0] to return u'2005'.

The ${request.route_url('recall_year', year=year[0]) tells system to provide a link to route name in views.py called recall_year and pass parameter year with value of year[0]

query with the parameter passed via url

Now lets move on to recall_make, do the query for make based on year passed in request

Edit views.py

@view_config(route_name='recall_year', renderer='recall.html')
def recall_year(request):
    makes=DBSession.query(Recall.MAKETXT).filter(Recall.YEARTXT==request.matchdict['year']).group_by(Recall.MAKETXT)
    return {'project':'Myapp_year','cyear':request.matchdict['year'],'makes':makes}
  • cyear will be used for "You are browsing XXXX year"
  • makes is the query that lists all makes based on the year supplied

Edit recall.html

<ul id="makes">
% if makes:
Click on Make of the vehicle:
  % for make in makes:
  <li>
    <span class="actions">
       <a href="${request.route_url('recall_make', year=cyear,make=make[0])}">${make[0]}</a>
    </span>
  </li>
  % endfor
% endif
</ul>

MyWiki: Pyramid/enterprise (last edited 2016-09-26 02:43:53 by LukaszSzybalski)