From 406024de0d1792cbca5056ceaa94ff19654f730e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 11 Nov 2015 21:28:28 -0800 Subject: basiclayout/tutorial/setup.py - update template binding from chameleon to jinja2 --- docs/tutorials/wiki2/src/basiclayout/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.py b/docs/tutorials/wiki2/src/basiclayout/setup.py index 15e7e5923..eb771010f 100644 --- a/docs/tutorials/wiki2/src/basiclayout/setup.py +++ b/docs/tutorials/wiki2/src/basiclayout/setup.py @@ -10,7 +10,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'pyramid', - 'pyramid_chameleon', + 'pyramid_jinja2', 'pyramid_debugtoolbar', 'pyramid_tm', 'SQLAlchemy', -- cgit v1.2.3 From 392cc17f5091d51a8e1b8908f8600c0b821ebd7f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 11 Nov 2015 21:58:03 -0800 Subject: basiclayout/tutorial - views - use package instead of single file - add tests.py from scaffold - update basiclayout.rst with views section --- .../wiki2/src/basiclayout/tutorial/tests.py | 68 ++++++++++++++++------ .../wiki2/src/basiclayout/tutorial/views.py | 35 ----------- .../src/basiclayout/tutorial/views/__init__.py | 0 .../src/basiclayout/tutorial/views/default.py | 33 +++++++++++ 4 files changed, 83 insertions(+), 53 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/views.py create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/views/__init__.py create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py index 57a775e0a..b947e3bb1 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/tests.py @@ -3,31 +3,63 @@ import transaction from pyramid import testing -from .models import DBSession +def dummy_request(dbsession): + return testing.DummyRequest(dbsession=dbsession) -class TestMyView(unittest.TestCase): + +class BaseTest(unittest.TestCase): def setUp(self): - self.config = testing.setUp() - from sqlalchemy import create_engine - engine = create_engine('sqlite://') - from .models import ( - Base, - MyModel, + self.config = testing.setUp(settings={ + 'sqlalchemy.url': 'sqlite:///:memory:' + }) + self.config.include('.models.meta') + settings = self.config.get_settings() + + from .models.meta import ( + get_session, + get_engine, + get_dbmaker, ) - DBSession.configure(bind=engine) - Base.metadata.create_all(engine) - with transaction.manager: - model = MyModel(name='one', value=55) - DBSession.add(model) + + self.engine = get_engine(settings) + dbmaker = get_dbmaker(self.engine) + + self.session = get_session(transaction.manager, dbmaker) + + def init_database(self): + from .models.meta import Base + Base.metadata.create_all(self.engine) def tearDown(self): - DBSession.remove() + from .models.meta import Base + testing.tearDown() + transaction.abort() + Base.metadata.create_all(self.engine) + + +class TestMyViewSuccessCondition(BaseTest): - def test_it(self): - from .views import my_view - request = testing.DummyRequest() - info = my_view(request) + def setUp(self): + super(TestMyViewSuccessCondition, self).setUp() + self.init_database() + + from .models.mymodel import MyModel + + model = MyModel(name='one', value=55) + self.session.add(model) + + def test_passing_view(self): + from .views.default import my_view + info = my_view(dummy_request(self.session)) self.assertEqual(info['one'].name, 'one') self.assertEqual(info['project'], 'tutorial') + + +class TestMyViewFailureCondition(BaseTest): + + def test_failing_view(self): + from .views.default import my_view + info = my_view(dummy_request(self.session)) + self.assertEqual(info.status_int, 500) diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/views.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/views.py deleted file mode 100644 index 4cfcae4af..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/views.py +++ /dev/null @@ -1,35 +0,0 @@ -from pyramid.response import Response -from pyramid.view import view_config - -from sqlalchemy.exc import DBAPIError - -from .models import ( - DBSession, - MyModel, - ) - - -@view_config(route_name='home', renderer='templates/mytemplate.pt') -def my_view(request): - try: - one = DBSession.query(MyModel).filter(MyModel.name == 'one').first() - except DBAPIError: - return Response(conn_err_msg, content_type='text/plain', status_int=500) - return {'one': one, 'project': 'tutorial'} - -conn_err_msg = """\ -Pyramid is having a problem using your SQL database. The problem -might be caused by one of the following things: - -1. You may need to run the "initialize_tutorial_db" script - to initialize your database tables. Check your virtual - environment's "bin" directory for this script and try to run it. - -2. Your database server may not be running. Check that the - database server referred to by the "sqlalchemy.url" setting in - your "development.ini" file is running. - -After you fix the problem, please restart the Pyramid application to -try it again. -""" - diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/__init__.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py new file mode 100644 index 000000000..13ad8793c --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py @@ -0,0 +1,33 @@ +from pyramid.response import Response +from pyramid.view import view_config + +from sqlalchemy.exc import DBAPIError + +from ..models.mymodel import MyModel + + +@view_config(route_name='home', renderer='../templates/mytemplate.jinja2') +def my_view(request): + try: + query = request.dbsession.query(MyModel) + one = query.filter(MyModel.name == 'one').first() + except DBAPIError: + return Response(db_err_msg, content_type='text/plain', status_int=500) + return {'one': one, 'project': 'tutorial'} + + +db_err_msg = """\ +Pyramid is having a problem using your SQL database. The problem +might be caused by one of the following things: + +1. You may need to run the "initialize_tutorial_db" script + to initialize your database tables. Check your virtual + environment's "bin" directory for this script and try to run it. + +2. Your database server may not be running. Check that the + database server referred to by the "sqlalchemy.url" setting in + your "development.ini" file is running. + +After you fix the problem, please restart the Pyramid application to +try it again. +""" -- cgit v1.2.3 From 0409cf178d4c0fa9a0d3b0858ab2294935b23609 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 12 Nov 2015 00:40:02 -0800 Subject: basiclayout/tutorial - models, scripts, static, templates - use package instead of single file - add tests.py from scaffold - update basiclayout.rst with models section --- .../wiki2/src/basiclayout/tutorial/models.py | 27 --------- .../src/basiclayout/tutorial/models/__init__.py | 7 +++ .../wiki2/src/basiclayout/tutorial/models/meta.py | 46 +++++++++++++++ .../src/basiclayout/tutorial/models/mymodel.py | 17 ++++++ .../basiclayout/tutorial/scripts/initializedb.py | 30 ++++++---- .../src/basiclayout/tutorial/static/theme.min.css | 2 +- .../basiclayout/tutorial/templates/layout.jinja2 | 66 ++++++++++++++++++++++ .../tutorial/templates/mytemplate.jinja2 | 8 +++ .../basiclayout/tutorial/templates/mytemplate.pt | 66 ---------------------- 9 files changed, 164 insertions(+), 105 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/models.py create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/models/meta.py create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/models/mymodel.py create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 delete mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py deleted file mode 100644 index 11ddccadb..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/models.py +++ /dev/null @@ -1,27 +0,0 @@ -from sqlalchemy import ( - Column, - Integer, - Text, - Index, - ) - -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 MyModel(Base): - __tablename__ = 'models' - id = Column(Integer, primary_key=True) - name = Column(Text, unique=True) - value = Column(Integer) - -Index('my_index', MyModel.name, unique=True, mysql_length=255) diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py new file mode 100644 index 000000000..6ffc10a78 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/__init__.py @@ -0,0 +1,7 @@ +from sqlalchemy.orm import configure_mappers +# import all models classes here for sqlalchemy mappers +# to pick up +from .mymodel import MyModel # flake8: noqa + +# run configure mappers to ensure we avoid any race conditions +configure_mappers() diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models/meta.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/meta.py new file mode 100644 index 000000000..b72b45f9f --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/meta.py @@ -0,0 +1,46 @@ +from sqlalchemy import engine_from_config +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import sessionmaker +from sqlalchemy.schema import MetaData +import zope.sqlalchemy + +NAMING_CONVENTION = { + "ix": 'ix_%(column_0_label)s', + "uq": "uq_%(table_name)s_%(column_0_name)s", + "ck": "ck_%(table_name)s_%(constraint_name)s", + "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s", + "pk": "pk_%(table_name)s" +} + +metadata = MetaData(naming_convention=NAMING_CONVENTION) +Base = declarative_base(metadata=metadata) + + +def includeme(config): + settings = config.get_settings() + dbmaker = get_dbmaker(get_engine(settings)) + + config.add_request_method( + lambda r: get_session(r.tm, dbmaker), + 'dbsession', + reify=True + ) + + config.include('pyramid_tm') + + +def get_session(transaction_manager, dbmaker): + dbsession = dbmaker() + zope.sqlalchemy.register(dbsession, + transaction_manager=transaction_manager) + return dbsession + + +def get_engine(settings, prefix='sqlalchemy.'): + return engine_from_config(settings, prefix) + + +def get_dbmaker(engine): + dbmaker = sessionmaker() + dbmaker.configure(bind=engine) + return dbmaker diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/models/mymodel.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/mymodel.py new file mode 100644 index 000000000..5a2b5890c --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/models/mymodel.py @@ -0,0 +1,17 @@ +from .meta import Base +from sqlalchemy import ( + Column, + Index, + Integer, + Text, +) + + +class MyModel(Base): + __tablename__ = 'models' + id = Column(Integer, primary_key=True) + name = Column(Text) + value = Column(Integer) + + +Index('my_index', MyModel.name, unique=True, mysql_length=255) diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initializedb.py index 66feb3008..f0d09729e 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initializedb.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initializedb.py @@ -2,36 +2,44 @@ import os import sys import transaction -from sqlalchemy import engine_from_config - from pyramid.paster import ( get_appsettings, setup_logging, ) -from ..models import ( - DBSession, - MyModel, +from pyramid.scripts.common import parse_vars + +from ..models.meta import ( Base, + get_session, + get_engine, + get_dbmaker, ) +from ..models.mymodel import MyModel def usage(argv): cmd = os.path.basename(argv[0]) - print('usage: %s \n' + print('usage: %s [var=value]\n' '(example: "%s development.ini")' % (cmd, cmd)) sys.exit(1) def main(argv=sys.argv): - if len(argv) != 2: + if len(argv) < 2: usage(argv) config_uri = argv[1] + options = parse_vars(argv[2:]) setup_logging(config_uri) - settings = get_appsettings(config_uri) - engine = engine_from_config(settings, 'sqlalchemy.') - DBSession.configure(bind=engine) + settings = get_appsettings(config_uri, options=options) + + engine = get_engine(settings) + dbmaker = get_dbmaker(engine) + + dbsession = get_session(transaction.manager, dbmaker) + Base.metadata.create_all(engine) + with transaction.manager: model = MyModel(name='one', value=1) - DBSession.add(model) + dbsession.add(model) diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/theme.min.css b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/theme.min.css index 2f924bcc5..0d25de5b6 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/static/theme.min.css +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/static/theme.min.css @@ -1 +1 @@ -@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a{color:#fff}.starter-template .links ul li a:hover{text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} \ No newline at end of file +@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);body{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300;color:#fff;background:#bc2131}h1,h2,h3,h4,h5,h6{font-family:"Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight:300}p{font-weight:300}.font-normal{font-weight:400}.font-semi-bold{font-weight:600}.font-bold{font-weight:700}.starter-template{margin-top:250px}.starter-template .content{margin-left:10px}.starter-template .content h1{margin-top:10px;font-size:60px}.starter-template .content h1 .smaller{font-size:40px;color:#f2b7bd}.starter-template .content .lead{font-size:25px;color:#f2b7bd}.starter-template .content .lead .font-normal{color:#fff}.starter-template .links{float:right;right:0;margin-top:125px}.starter-template .links ul{display:block;padding:0;margin:0}.starter-template .links ul li{list-style:none;display:inline;margin:0 10px}.starter-template .links ul li:first-child{margin-left:0}.starter-template .links ul li:last-child{margin-right:0}.starter-template .links ul li.current-version{color:#f2b7bd;font-weight:400}.starter-template .links ul li a,a{color:#f2b7bd;text-decoration:underline}.starter-template .links ul li a:hover,a:hover{color:#fff;text-decoration:underline}.starter-template .links ul li .icon-muted{color:#eb8b95;margin-right:5px}.starter-template .links ul li:hover .icon-muted{color:#fff}.starter-template .copyright{margin-top:10px;font-size:.9em;color:#f2b7bd;text-transform:lowercase;float:right;right:0}@media (max-width:1199px){.starter-template .content h1{font-size:45px}.starter-template .content h1 .smaller{font-size:30px}.starter-template .content .lead{font-size:20px}}@media (max-width:991px){.starter-template{margin-top:0}.starter-template .logo{margin:40px auto}.starter-template .content{margin-left:0;text-align:center}.starter-template .content h1{margin-bottom:20px}.starter-template .links{float:none;text-align:center;margin-top:60px}.starter-template .copyright{float:none;text-align:center}}@media (max-width:767px){.starter-template .content h1 .smaller{font-size:25px;display:block}.starter-template .content .lead{font-size:16px}.starter-template .links{margin-top:40px}.starter-template .links ul li{display:block;margin:0}.starter-template .links ul li .icon-muted{display:none}.starter-template .copyright{margin-top:20px}} diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 new file mode 100644 index 000000000..ff624c65b --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 @@ -0,0 +1,66 @@ + + + + + + + + + + + Alchemy Scaffold for The Pyramid Web Framework + + + + + + + + + + + + + +
+
+
+
+ +
+
+ {% block content %} +

No content

+ {% endblock content %} +
+
+
+ +
+
+ +
+
+
+ + + + + + + + diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 new file mode 100644 index 000000000..bb622bf5a --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.jinja2 @@ -0,0 +1,8 @@ +{% extends "layout.jinja2" %} + +{% block content %} +
+

Pyramid Alchemy scaffold

+

Welcome to {{project}}, an application generated by
the Pyramid Web Framework 1.7.dev0.

+
+{% endblock content %} diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt deleted file mode 100644 index c9b0cec21..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/mytemplate.pt +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - Alchemy Scaffold for The Pyramid Web Framework - - - - - - - - - - - - - -
-
-
-
- -
-
-
-

Pyramid Alchemy scaffold

-

Welcome to ${project}, an application generated by
the Pyramid Web Framework.

-
-
-
- -
- -
-
-
- - - - - - - - -- cgit v1.2.3