summaryrefslogtreecommitdiff
path: root/docs/quick_tutorial/databases
diff options
context:
space:
mode:
authorPaul Everitt <paul@agendaless.com>2013-09-13 16:52:14 -0400
committerPaul Everitt <paul@agendaless.com>2013-09-13 16:52:14 -0400
commitb1b92284f496800a4dfd2cea72cb9be07ba8661c (patch)
tree9dfa72427fd6aa0a3a7aaba72be4a4e49380ee26 /docs/quick_tutorial/databases
parent1d04f8f0b483b8d595f5ada24ae5108affe80160 (diff)
downloadpyramid-b1b92284f496800a4dfd2cea72cb9be07ba8661c.tar.gz
pyramid-b1b92284f496800a4dfd2cea72cb9be07ba8661c.tar.bz2
pyramid-b1b92284f496800a4dfd2cea72cb9be07ba8661c.zip
First cut at import of quick tutorial.
Diffstat (limited to 'docs/quick_tutorial/databases')
-rw-r--r--docs/quick_tutorial/databases/development.ini49
-rw-r--r--docs/quick_tutorial/databases/setup.py20
-rw-r--r--docs/quick_tutorial/databases/sqltutorial.sqlitebin0 -> 12288 bytes
-rw-r--r--docs/quick_tutorial/databases/tutorial/__init__.py20
-rw-r--r--docs/quick_tutorial/databases/tutorial/initialize_db.py37
-rw-r--r--docs/quick_tutorial/databases/tutorial/models.py35
-rw-r--r--docs/quick_tutorial/databases/tutorial/tests.py58
-rw-r--r--docs/quick_tutorial/databases/tutorial/views.py96
-rw-r--r--docs/quick_tutorial/databases/tutorial/wiki_view.pt19
-rw-r--r--docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt22
-rw-r--r--docs/quick_tutorial/databases/tutorial/wikipage_view.pt17
11 files changed, 373 insertions, 0 deletions
diff --git a/docs/quick_tutorial/databases/development.ini b/docs/quick_tutorial/databases/development.ini
new file mode 100644
index 000000000..270da960f
--- /dev/null
+++ b/docs/quick_tutorial/databases/development.ini
@@ -0,0 +1,49 @@
+[app:main]
+use = egg:tutorial
+pyramid.reload_templates = true
+pyramid.includes =
+ pyramid_debugtoolbar
+ pyramid_tm
+
+sqlalchemy.url = sqlite:///%(here)s/sqltutorial.sqlite
+
+[server:main]
+use = egg:pyramid#wsgiref
+host = 0.0.0.0
+port = 6543
+
+# Begin logging configuration
+
+[loggers]
+keys = root, tutorial, sqlalchemy
+
+[logger_tutorial]
+level = DEBUG
+handlers =
+qualname = tutorial
+
+[logger_sqlalchemy]
+level = INFO
+handlers =
+qualname = sqlalchemy.engine
+
+[handlers]
+keys = console
+
+[formatters]
+keys = generic
+
+[logger_root]
+level = INFO
+handlers = console
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[formatter_generic]
+format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
+
+# End logging configuration
diff --git a/docs/quick_tutorial/databases/setup.py b/docs/quick_tutorial/databases/setup.py
new file mode 100644
index 000000000..5cb197c39
--- /dev/null
+++ b/docs/quick_tutorial/databases/setup.py
@@ -0,0 +1,20 @@
+from setuptools import setup
+
+requires = [
+ 'pyramid',
+ 'deform',
+ 'sqlalchemy',
+ 'pyramid_tm',
+ 'zope.sqlalchemy',
+ 'pysqlite'
+]
+
+setup(name='tutorial',
+ install_requires=requires,
+ entry_points="""\
+ [paste.app_factory]
+ main = tutorial:main
+ [console_scripts]
+ initialize_tutorial_db = tutorial.initialize_db:main
+ """,
+) \ No newline at end of file
diff --git a/docs/quick_tutorial/databases/sqltutorial.sqlite b/docs/quick_tutorial/databases/sqltutorial.sqlite
new file mode 100644
index 000000000..b8bd856fd
--- /dev/null
+++ b/docs/quick_tutorial/databases/sqltutorial.sqlite
Binary files differ
diff --git a/docs/quick_tutorial/databases/tutorial/__init__.py b/docs/quick_tutorial/databases/tutorial/__init__.py
new file mode 100644
index 000000000..47e8fefa6
--- /dev/null
+++ b/docs/quick_tutorial/databases/tutorial/__init__.py
@@ -0,0 +1,20 @@
+from pyramid.config import Configurator
+
+from sqlalchemy import engine_from_config
+
+from .models import DBSession, Base
+
+def main(global_config, **settings):
+ engine = engine_from_config(settings, 'sqlalchemy.')
+ DBSession.configure(bind=engine)
+ Base.metadata.bind = engine
+
+ config = Configurator(settings=settings,
+ root_factory='tutorial.models.Root')
+ config.add_route('wiki_view', '/')
+ config.add_route('wikipage_add', '/add')
+ config.add_route('wikipage_view', '/{uid}')
+ config.add_route('wikipage_edit', '/{uid}/edit')
+ config.add_static_view('deform_static', 'deform:static/')
+ config.scan('.views')
+ return config.make_wsgi_app() \ No newline at end of file
diff --git a/docs/quick_tutorial/databases/tutorial/initialize_db.py b/docs/quick_tutorial/databases/tutorial/initialize_db.py
new file mode 100644
index 000000000..98be524a1
--- /dev/null
+++ b/docs/quick_tutorial/databases/tutorial/initialize_db.py
@@ -0,0 +1,37 @@
+import os
+import sys
+import transaction
+
+from sqlalchemy import engine_from_config
+
+from pyramid.paster import (
+ get_appsettings,
+ setup_logging,
+ )
+
+from .models import (
+ DBSession,
+ Page,
+ Base,
+ )
+
+
+def usage(argv):
+ cmd = os.path.basename(argv[0])
+ print('usage: %s <config_uri>\n'
+ '(example: "%s development.ini")' % (cmd, cmd))
+ sys.exit(1)
+
+
+def main(argv=sys.argv):
+ if len(argv) != 2:
+ usage(argv)
+ config_uri = argv[1]
+ setup_logging(config_uri)
+ settings = get_appsettings(config_uri)
+ engine = engine_from_config(settings, 'sqlalchemy.')
+ DBSession.configure(bind=engine)
+ Base.metadata.create_all(engine)
+ with transaction.manager:
+ model = Page(title='Root', body='<p>Root</p>')
+ DBSession.add(model)
diff --git a/docs/quick_tutorial/databases/tutorial/models.py b/docs/quick_tutorial/databases/tutorial/models.py
new file mode 100644
index 000000000..b27c38417
--- /dev/null
+++ b/docs/quick_tutorial/databases/tutorial/models.py
@@ -0,0 +1,35 @@
+from pyramid.security import Allow, Everyone
+
+from sqlalchemy import (
+ Column,
+ Integer,
+ Text,
+ )
+
+from sqlalchemy.ext.declarative import declarative_base
+
+from sqlalchemy.orm import (
+ scoped_session,
+ sessionmaker,
+ )
+
+from zope.sqlalchemy import ZopeTransactionExtension
+
+DBSession = scoped_session(
+ sessionmaker(extension=ZopeTransactionExtension()))
+Base = declarative_base()
+
+
+class Page(Base):
+ __tablename__ = 'wikipages'
+ uid = Column(Integer, primary_key=True)
+ title = Column(Text, unique=True)
+ body = Column(Text)
+
+
+class Root(object):
+ __acl__ = [(Allow, Everyone, 'view'),
+ (Allow, 'group:editors', 'edit')]
+
+ def __init__(self, request):
+ pass \ No newline at end of file
diff --git a/docs/quick_tutorial/databases/tutorial/tests.py b/docs/quick_tutorial/databases/tutorial/tests.py
new file mode 100644
index 000000000..e18e70c8c
--- /dev/null
+++ b/docs/quick_tutorial/databases/tutorial/tests.py
@@ -0,0 +1,58 @@
+import unittest
+import transaction
+
+from pyramid import testing
+
+
+def _initTestingDB():
+ from sqlalchemy import create_engine
+ from .models import (
+ DBSession,
+ Page,
+ Base
+ )
+ engine = create_engine('sqlite://')
+ Base.metadata.create_all(engine)
+ DBSession.configure(bind=engine)
+ with transaction.manager:
+ model = Page(title='FrontPage', body='This is the front page')
+ DBSession.add(model)
+ return DBSession
+
+
+class WikiViewTests(unittest.TestCase):
+ def setUp(self):
+ self.session = _initTestingDB()
+ self.config = testing.setUp()
+
+ def tearDown(self):
+ self.session.remove()
+ testing.tearDown()
+
+ def test_wiki_view(self):
+ from tutorial.views import WikiViews
+
+ request = testing.DummyRequest()
+ inst = WikiViews(request)
+ response = inst.wiki_view()
+ self.assertEqual(response['title'], 'Wiki View')
+
+
+class WikiFunctionalTests(unittest.TestCase):
+ def setUp(self):
+ self.session = _initTestingDB()
+ self.config = testing.setUp()
+ from pyramid.paster import get_app
+ app = get_app('development.ini')
+ from webtest import TestApp
+ self.testapp = TestApp(app)
+
+ def tearDown(self):
+ self.session.remove()
+ testing.tearDown()
+
+ def test_it(self):
+ res = self.testapp.get('/', status=200)
+ self.assertIn(b'Wiki: View', res.body)
+ res = self.testapp.get('/add', status=200)
+ self.assertIn(b'Add/Edit', res.body)
diff --git a/docs/quick_tutorial/databases/tutorial/views.py b/docs/quick_tutorial/databases/tutorial/views.py
new file mode 100644
index 000000000..4608c6d43
--- /dev/null
+++ b/docs/quick_tutorial/databases/tutorial/views.py
@@ -0,0 +1,96 @@
+import colander
+import deform.widget
+
+from pyramid.httpexceptions import HTTPFound
+from pyramid.view import view_config
+
+from .models import DBSession, Page
+
+
+class WikiPage(colander.MappingSchema):
+ title = colander.SchemaNode(colander.String())
+ body = colander.SchemaNode(
+ colander.String(),
+ widget=deform.widget.RichTextWidget()
+ )
+
+
+class WikiViews(object):
+ def __init__(self, request):
+ self.request = request
+
+ @property
+ def wiki_form(self):
+ schema = WikiPage()
+ return deform.Form(schema, buttons=('submit',))
+
+ @property
+ def reqts(self):
+ return self.wiki_form.get_widget_resources()
+
+ @view_config(route_name='wiki_view', renderer='wiki_view.pt')
+ def wiki_view(self):
+ pages = DBSession.query(Page).order_by(Page.title)
+ return dict(title='Wiki View', pages=pages)
+
+ @view_config(route_name='wikipage_add',
+ renderer='wikipage_addedit.pt')
+ def wikipage_add(self):
+ form = self.wiki_form.render()
+
+ if 'submit' in self.request.params:
+ controls = self.request.POST.items()
+ try:
+ appstruct = self.wiki_form.validate(controls)
+ except deform.ValidationFailure as e:
+ # Form is NOT valid
+ return dict(form=e.render())
+
+ # Add a new page to the database
+ new_title = appstruct['title']
+ new_body = appstruct['body']
+ DBSession.add(Page(title=new_title, body=new_body))
+
+ # Get the new ID and redirect
+ page = DBSession.query(Page).filter_by(title=new_title).one()
+ new_uid = page.uid
+
+ url = self.request.route_url('wikipage_view', uid=new_uid)
+ return HTTPFound(url)
+
+ return dict(form=form)
+
+
+ @view_config(route_name='wikipage_view', renderer='wikipage_view.pt')
+ def wikipage_view(self):
+ uid = int(self.request.matchdict['uid'])
+ page = DBSession.query(Page).filter_by(uid=uid).one()
+ return dict(page=page)
+
+
+ @view_config(route_name='wikipage_edit',
+ renderer='wikipage_addedit.pt')
+ def wikipage_edit(self):
+ uid = int(self.request.matchdict['uid'])
+ page = DBSession.query(Page).filter_by(uid=uid).one()
+
+ wiki_form = self.wiki_form
+
+ if 'submit' in self.request.params:
+ controls = self.request.POST.items()
+ try:
+ appstruct = wiki_form.validate(controls)
+ except deform.ValidationFailure as e:
+ return dict(page=page, form=e.render())
+
+ # Change the content and redirect to the view
+ page.title = appstruct['title']
+ page.body = appstruct['body']
+ url = self.request.route_url('wikipage_view', uid=uid)
+ return HTTPFound(url)
+
+ form = self.wiki_form.render(dict(
+ uid=page.uid, title=page.title, body=page.body)
+ )
+
+ return dict(page=page, form=form)
diff --git a/docs/quick_tutorial/databases/tutorial/wiki_view.pt b/docs/quick_tutorial/databases/tutorial/wiki_view.pt
new file mode 100644
index 000000000..9e3afe495
--- /dev/null
+++ b/docs/quick_tutorial/databases/tutorial/wiki_view.pt
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>Wiki: View</title>
+</head>
+<body>
+<h1>Wiki</h1>
+
+<a href="${request.route_url('wikipage_add')}">Add
+ WikiPage</a>
+<ul>
+ <li tal:repeat="page pages">
+ <a href="${request.route_url('wikipage_view', uid=page.uid)}">
+ ${page.title}
+ </a>
+ </li>
+</ul>
+</body>
+</html> \ No newline at end of file
diff --git a/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt
new file mode 100644
index 000000000..d1fea0d7f
--- /dev/null
+++ b/docs/quick_tutorial/databases/tutorial/wikipage_addedit.pt
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>WikiPage: Add/Edit</title>
+ <tal:block tal:repeat="reqt view.reqts['css']">
+ <link rel="stylesheet" type="text/css"
+ href="${request.static_url('deform:static/' + reqt)}"/>
+ </tal:block>
+ <tal:block tal:repeat="reqt view.reqts['js']">
+ <script src="${request.static_url('deform:static/' + reqt)}"
+ type="text/javascript"></script>
+ </tal:block>
+</head>
+<body>
+<h1>Wiki</h1>
+
+<p>${structure: form}</p>
+<script type="text/javascript">
+ deform.load()
+</script>
+</body>
+</html>
diff --git a/docs/quick_tutorial/databases/tutorial/wikipage_view.pt b/docs/quick_tutorial/databases/tutorial/wikipage_view.pt
new file mode 100644
index 000000000..cb9ff526e
--- /dev/null
+++ b/docs/quick_tutorial/databases/tutorial/wikipage_view.pt
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <title>WikiPage: View</title>
+</head>
+<body>
+<a href="${request.route_url('wiki_view')}">
+ Up
+</a> |
+<a href="${request.route_url('wikipage_edit', uid=page.uid)}">
+ Edit
+</a>
+
+<h1>${page.title}</h1>
+<p>${structure: page.body}</p>
+</body>
+</html> \ No newline at end of file