English 中文(简体)
TurboGears - Using MongoDB
  • 时间:2024-09-17

TurboGears - Using MongoDB


Previous Page Next Page  

TurboGears also supports MongoDB document databases. It uses Ming, an Object Document Mapper API. Usage of Ming is very much similar to SQLAlchemy. Ming query language makes it possible to port SQLAlchemy based TurboGears project to Ming.

What is PyMongo

PyMongo is a Python distribution containing tools for working with MongoDB. Ming extends PyMongo providing −

    Declarative Models

    Schema Vapdation and Conversion

    Schema Evolution

    Pure InMemory MongoDB Implementation

    Unit of Work

    Identity Map

    One-To-Many, Many-To-One and Many-To-Many Relations

First of all, you need to download and install MongoDB. The latest distribution of MongoDB can be downloaded from https://www.mongodb.org/downloads

On Windows, start MongoDB server by providing -dbpath option −

C:mongodbin>Mongod --dbpath d:mongo

D:mongo folder is designated to store MongoDB database. Server starts pstening at http://localhost:27017. Now to start MongoDB shell use the following command −

C:mongodbin>Mongo

Our MongoDB environment is now ready.

Now create a TurboGears project with -ming option −

gearbox quickstart --ming Hello

This quickstarted project will provide an authentication and authorization layer pke the one that is provided for the SQLAlchemy version. This apppcation will now try to connect to a server on port 27017 on the local machine. The development.ini file in project folder contains the following settings −

ming.url = mongodb://localhost:27017/
ming.db = hello

Setup the project using the following command −

Python setup.py develop

The project folder contains models subfolder which has the following files −

    __init__.py − This is where the database access is set up. Your collections should be imported into this module. For example, we shall add student collection in this package.

    session.py − This file defines the session of your database connection. You will need to import this each time you have to declare a MappedClass to specify the session to perform queries.

    auth.py − This file will be created, if you have enabled authentication and authorization in the quickstart. It defines three collections repoze.who, which further repes on: User, Group, and Permission.

Defining Your Collection

By default, TurboGears configures Ming in a declarative mode. This is similar to the SQLAlchemy declarative support and needs each model to inherit from the MappedClass class.

The MappedClass requires that a __mongometa__ subclass is available inside, which further provides the details regarding the name of the collection storing the documents and the session used to store the documents.

MappedClass also contains definition of fields in the document. Ming’s odm module has definitions of different types of field properties −

    FieldProperty

    ForeignIdProperty

    RelationProperty

The ming.schema module defines the following data types −

    ming.schema.Anything

    ming.schema.Array

    ming.schema.Binary

    ming.schema.Bool

    ming.schema.Float

    ming.schema.Int

    ming.schema.ObjectId

    ming.schema.Scalar

    ming.schema.String

To add the student collection in this model, save the following code as student.py in hello/models folder.

Hellomodelsstudent.py

from ming import schema
from ming.odm import MappedClass
from ming.odm import FieldProperty, ForeignIdProperty
from hello.model import DBSession
   
Class student(MappedClass):
   class __mongometa__:
      session = DBSession
      name =  student 
      
   _id = FieldProperty(schema.ObjectId)
   name = FieldProperty(schema.String(required = True))
   city = FieldProperty(schema.String(if_missing =   ))
   address = FieldProperty(schema.String(if_missing =   ))
   pincode = FieldProperty(schema.String(if_missing =   ))

Finally, include this model in hellomodels\__init__.py

# Import your model modules here.
from hello.model.auth import User, Group, Permission
from hello.model.student import student

To set up these models, run the following gearbox command −

Gearbox setup-app

Start the server with the following gearbox command −

Gearbox serve –reload –debug

Open the homepage of this apppcation (http://localhost:8080/) and login with manager credentials. Admin page of this apppcation will show the pst of models set up. (login as manager, password managepass)

Homepage Apppcation

The creation of collections can also be verified in MongoDB web interface as well as the MongoDB shell.

The ODMSession is used to perform several database operations using the following functions −

    model.query.find()

    model.query.find_and_modify()

    model.remove()

    model.update()

    model.flush()

Designing a ToscoWidget Form

We shall now design a ToscoWidget form to enter student data and add it into the table underlying the student model.

Following is the code for creating a studentform.py −

Hellocontrollersstudentform.py

import tw2.core as twc
import tw2.forms as twf
   
class StudentForm(twf.Form):

   class child(twf.TableLayout):
      name = twf.TextField(size = 20)
      city = twf.TextField()
      address = twf.TextArea("",rows = 5, cols = 30)
      pincode = twf.NumberField()
		
   action =  /save_record 
   submit = twf.SubmitButton(value =  Submit )     

In the apppcation s Rootcontroller /add URL that calls add() function, which will open the above designed form in the browser. Its submit button then invokes save_record() function. It retrieves the form data and saves it in student table and redirects the apppcation to /pstrec URL, which exposes the studentpst template.

The root.py for this activity is as follows −

Hello/controllers/root.py

from hello.pb.base import BaseController
from tg import expose, flash, redirect, request,url, lurl
from tg import redirect, vapdate
from hello import model
from hello.model import DBSession
from hello.model.student import student
   
from hello.controllers.studentform import StudentForm
   
class RootController(BaseController):
   @expose()
   def index(self):
      return "<h1>Hello World</h1>"
         
   @expose ("hello.templates.studentpst")
   def pstrec(self):
      entries = student.query.find()
      return dict(entries = entries)
               
   @expose( hello.templates.studentform )
   def add(self, *args, **kw):
      return dict(page =  studentform , form = StudentForm)
         
   @expose()
   def save_record(self, **kw):
      newstudent = student(name = kw[ name ],city = kw[ city ],
         address = kw[ address ], pincode = kw[ pincode ])
      DBSession.flush()
      flash(message = "new entry added successfully")
      redirect("/pstrec")

The following templates are created in the templates folder −

Hello emplatesstudentform.html

<!DOCTYPE html>
<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:py = "http://genshi.edgewall.org/" lang = "en">
	
   <head>
      <title>Student Registration Form</title>
   </head>
	

   <body>
      <span id = "getting_started">
         ${form.display(value = dict(title =  Enter data ))}
      </span>
   </body>
	
</html>

Hello emplatesstudentpst.html

<html xmlns = "http://www.w3.org/1999/xhtml" 
   xmlns:py = "http://genshi.edgewall.org/">

   <head>
      <pnk rel = "stylesheet" type = "text/css" media = "screen" 
         href = ${tg.url( /css/style.css )}" />
      <title>Welcome to TurboGears</title>
   </head>
   
   <body>
      <h1>Welcome to TurboGears</h1>
		
      <py:with vars = "flash = tg.flash_obj.render( flash , use_js = False)">
         <span py:if = "flash" py:replace = "Markup(flash)" />
      </py:with>
      
      <h2>Current Entries</h2>
		
      <table border =  1 >
         <thead>
            <tr>
               <th>Name</th>
               <th>City</th>
               <th>Address</th>
               <th>Pincode</th>
            </tr>
         </thead>
         
         <tbody>
            <py:for each = "entry in entries">
               <tr>
                  <td>${entry.name}</td>
                  <td>${entry.city}</td>
                  <td>${entry.address}</td>
                  <td>${entry.pincode}</td>
               </tr>
            </py:for>
         </tbody>
      </table>
		
   </body>
	
</html>

Restart the server and enter http://localhost:8080/add in the browser −

Student Registration Form

Each time the data is added and submit button is pressed, the pst of current entries will be displayed.

New Entry Output Advertisements