[Checkins] SVN: grokapps/rdbexample/trunk/src/rdbexample/app Since URL generation now works, we can use templates as we expect to.
Martijn Faassen
faassen at infrae.com
Wed Aug 20 13:56:11 EDT 2008
Log message for revision 90036:
Since URL generation now works, we can use templates as we expect to.
Changed:
U grokapps/rdbexample/trunk/src/rdbexample/app.py
A grokapps/rdbexample/trunk/src/rdbexample/app_templates/departmentindex.pt
A grokapps/rdbexample/trunk/src/rdbexample/app_templates/departmentsindex.pt
A grokapps/rdbexample/trunk/src/rdbexample/app_templates/facultyindex.pt
A grokapps/rdbexample/trunk/src/rdbexample/app_templates/rdbexampleindex.pt
-=-
Modified: grokapps/rdbexample/trunk/src/rdbexample/app.py
===================================================================
--- grokapps/rdbexample/trunk/src/rdbexample/app.py 2008-08-20 17:42:48 UTC (rev 90035)
+++ grokapps/rdbexample/trunk/src/rdbexample/app.py 2008-08-20 17:56:11 UTC (rev 90036)
@@ -1,6 +1,8 @@
import grok
from megrok import rdb
+from zope.location.location import located
+
from sqlalchemy.schema import Column, ForeignKey
from sqlalchemy.types import Integer, String
from sqlalchemy.orm import relation
@@ -8,60 +10,118 @@
from z3c.saconfig import EngineFactory, GloballyScopedSession
from z3c.saconfig.interfaces import IEngineFactory, IEngineCreatedEvent
+# we set up the engine factory and the session
+# we set them up as global utilities here. It is also possible to
+# use a local engine factory and a special locally scoped session
TEST_DSN = 'sqlite:///:memory:'
-
+
engine_factory = EngineFactory(TEST_DSN)
scoped_session = GloballyScopedSession()
grok.global_utility(engine_factory, direct=True)
grok.global_utility(scoped_session, direct=True)
+# we set up the SQLAlchemy metadata object to which we'll associate all the
+# SQLAlchemy-backed objects
metadata = rdb.MetaData()
-class RDBExample(grok.Application, grok.Model):
- def traverse(self, name):
- try:
- key = int(name)
- except ValueError:
- return None
- session = rdb.Session()
- return session.query(Faculty).get(key)
+# we declare to megrok.rdb that all SQLAlchemy-managed mapped instances
+# are associated with this metadata. This directive can also be used
+# on a per rdb.Model subclass basis
+rdb.metadata(metadata)
+# we make sure that when the engine is created we set up the metadata for it
@grok.subscribe(IEngineCreatedEvent)
def setUpDatabase(event):
rdb.setupDatabase(metadata)
-class FacultyList(grok.View):
+class RDBExample(grok.Application, grok.Model, rdb.QueryContainer):
+ """The application object.
+
+ We mix in grok.Model to make it persistent so it can be installed using
+ the Grok UI.
+
+ We mix in rdb.QueryContainer to let it behave like a container. We
+ need to implement the query method to supply it with a query object.
+ """
+ def query(self):
+ session = rdb.Session()
+ # we allow browsing into any Faculty object
+ # we could've restricted this query so that it would only
+ # allow browsing to a subset
+ return session.query(Faculty)
+
+class RDBExampleIndex(grok.View):
+ """The index page for RDBExample. This shows all faculties available.
+ """
grok.name('index')
grok.context(RDBExample)
- def render(self):
- result = ""
+ def faculties(self):
session = rdb.Session()
for faculty in session.query(Faculty).all():
- result += "%s - %s (%s)" % (faculty.id, faculty.title,
- self.url(str(faculty.id)))
- return result
+ yield located(faculty, self.context, str(faculty.id))
+class AddFaculty(grok.AddForm):
+ """A form to add a new Faculty object to the application.
+ """
+ grok.context(RDBExample)
+
+ @property
+ def form_fields(self):
+ return rdb.Fields(Faculty)
+
+ @grok.action('add')
+ def handle_add(self, *args, **kw):
+ faculty = Faculty(**kw)
+ session = rdb.Session()
+ session.add(faculty)
+ self.redirect(self.url(self.context))
+
class Departments(rdb.Container):
+ """This container implements the departments relation on Faculty.
+ """
+
+ # we browse to departments using the title attribute of Department,
+ # which is assumed (or constrained) to be unique. By default this
+ # would use the primary key of Department for browsing.
rdb.key('title')
+
+class Faculty(rdb.Model):
+ """This model implements the faculty content object.
-class Faculty(rdb.Model):
+ It's backed by a relational database.
+ """
+
+ # we declare that the departments atribute can be browsed into
grok.traversable('departments')
- rdb.metadata(metadata)
-
+ # the attributes of a faculty, stored in the database
id = Column('id', Integer, primary_key=True)
title = Column('title', String(50))
+ # we declare a relation, using our special Departments class
departments = relation('Department',
backref='faculty',
collection_class=Departments)
+class FacultyIndex(grok.View):
+ """This is the default view for Faculty.
+ """
+ grok.name('index')
+ grok.context(Faculty)
+
class Department(rdb.Model):
- rdb.metadata(metadata)
+ """This model implements the department content object.
+
+ Each department is in a faculty.
+ It's backed by a relational database.
+ """
+
+ # the attributes of a department
id = Column('id', Integer, primary_key=True)
+ # the id of the faculty that this department is in
faculty_id = Column('faculty_id', Integer, ForeignKey('faculty.id'))
title = Column('title', String(50))
@@ -78,43 +138,13 @@
session = rdb.Session()
session.add(department)
self.context.set(department)
-
-class DepartmentView(grok.View):
+ self.redirect(self.url(self.context))
+
+class DepartmentIndex(grok.View):
grok.name('index')
grok.context(Department)
- def render(self):
- return "Department: %r - %r" % (self.context.id, self.context.title)
-
-class DepartmentList(grok.View):
+class DepartmentsIndex(grok.View):
grok.name('index')
- grok.context(Faculty)
-
- def render(self):
- result = "Faculty: %s - %s " % (self.context.id, self.context.title)
- for department in self.context.departments.values():
- result += department.title + '\n'
- return result
-
-class DepartmentsView(grok.View):
- grok.name('index')
grok.context(Departments)
- def render(self):
- result = ""
- for department in self.context.values():
- result += department.title + '\n'
- return result
-
-class AddFaculty(grok.AddForm):
- grok.context(RDBExample)
-
- @property
- def form_fields(self):
- return rdb.Fields(Faculty)
-
- @grok.action('add')
- def handle_add(self, *args, **kw):
- faculty = Faculty(**kw)
- session = rdb.Session()
- session.add(faculty)
Added: grokapps/rdbexample/trunk/src/rdbexample/app_templates/departmentindex.pt
===================================================================
--- grokapps/rdbexample/trunk/src/rdbexample/app_templates/departmentindex.pt (rev 0)
+++ grokapps/rdbexample/trunk/src/rdbexample/app_templates/departmentindex.pt 2008-08-20 17:56:11 UTC (rev 90036)
@@ -0,0 +1,5 @@
+<html>
+<body>
+<h2>Department <span tal:content="context/title"></span></h2>
+</body>
+</html>
Added: grokapps/rdbexample/trunk/src/rdbexample/app_templates/departmentsindex.pt
===================================================================
--- grokapps/rdbexample/trunk/src/rdbexample/app_templates/departmentsindex.pt (rev 0)
+++ grokapps/rdbexample/trunk/src/rdbexample/app_templates/departmentsindex.pt 2008-08-20 17:56:11 UTC (rev 90036)
@@ -0,0 +1,15 @@
+<html>
+<body>
+<h3>Departments of faculty <span tal:replace="context/__parent__/title"></span></h3>
+<ul>
+ <li tal:repeat="department context/values">
+ <a tal:attributes="href python:view.url(department)"
+ tal:content="department/title"></a>
+ </li>
+</ul>
+
+<p>
+ <a tal:attributes="href python:view.url(context, '@@adddepartment')">Add Department</a>
+</p>
+</body>
+</html>
Added: grokapps/rdbexample/trunk/src/rdbexample/app_templates/facultyindex.pt
===================================================================
--- grokapps/rdbexample/trunk/src/rdbexample/app_templates/facultyindex.pt (rev 0)
+++ grokapps/rdbexample/trunk/src/rdbexample/app_templates/facultyindex.pt 2008-08-20 17:56:11 UTC (rev 90036)
@@ -0,0 +1,11 @@
+<html>
+<body>
+<h2>Faculty <span tal:content="context/title"></span></h2>
+<h3>Departments</h3>
+
+<p>
+ <a tal:attributes="href python:view.url(context.departments)">Departments</a>
+</p>
+
+</body>
+</html>
Added: grokapps/rdbexample/trunk/src/rdbexample/app_templates/rdbexampleindex.pt
===================================================================
--- grokapps/rdbexample/trunk/src/rdbexample/app_templates/rdbexampleindex.pt (rev 0)
+++ grokapps/rdbexample/trunk/src/rdbexample/app_templates/rdbexampleindex.pt 2008-08-20 17:56:11 UTC (rev 90036)
@@ -0,0 +1,14 @@
+<html>
+<body>
+<h2>RDB Example</h2>
+<h3>Faculty listing</h3>
+<ul>
+ <li tal:repeat="faculty view/faculties">
+ <a tal:attributes="href python:view.url(faculty)" tal:content="faculty/title"></a>
+ </li>
+</ul>
+<p>
+ <a tal:attributes="href python:view.url('addfaculty')">Add Faculty</a>
+</p>
+</body>
+</html>
\ No newline at end of file
More information about the Checkins
mailing list