Question

I'm coming from a spaghetti code PHP background. I'm trying to learn MVC by cutting my teeth on Python with Flask and MongoDB. I think this question could apply to other situations. It's more of a newbie Python question. But this is where I'm running into it for the first time with this setup.

I'm using Flask with Blueprints to layout my app. I'm breaking down each major site feature into a sub directory of myapp (module/blueprint). Here is my directory structure

Dir structure

/proj/config.py
/proj/runserver.py
/proj/myapp/
/proj/myapp/__init__.py
/proj/myapp/static/
/proj/myapp/templates/
/proj/myapp/templates/users/
/proj/myapp/templates/forums/
/proj/myapp/templates/frontend/
/proj/myapp/users/
/proj/myapp/users/__init__.py
/proj/myapp/users/models.py
/proj/myapp/users/views.py
/proj/myapp/forums/ ..
/proj/myapp/frontend/ ..

So I'm trying to implement this simple MongoKit example. But instead of having it in one file. I need to spread it out across the MVC pattern.

MongoKit sample

from flask import Flask, request, render_template, redirect, url_for
from flask.ext.mongokit import MongoKit, Document

app = Flask(__name__)

class User(Document):
    __collection__ = 'user'
    structure = {
        'name': unicode,
        'email': unicode,
    }
    required_fields = ['name', 'email']
    use_dot_notation = True

db = MongoKit(app)
db.register([User])

The main part of my app is in init.py and it looks like:

/myapp/_init_.py

from flask import Flask, render_template, abort
from flask.ext.mongokit import MongoKit, Document

from .home.views import mod as home_blueprint
from .users.views import mod as user_blueprint
from .forums.views import mod as forum_blueprint

def create_app():
    app = Flask(__name__)
    app.config.from_object('config')

    # Register blueprints
    app.register_blueprint(home_blueprint)
    app.register_blueprint(user_blueprint, url_prefix="/users")
    app.register_blueprint(forum_blueprint, url_prefix="/forums")

    db = MongoKit(app)

    @app.errorhandler(404)
    def not_found(error):
        return render_template('404.html')

    @app.errorhandler(500)
    def internal_error(exception):
        return "Some internal error has taken place.  Alert somebody!"

    return app

And then I'm not quite sure what to do with the rest. I setup a class in /myapp/users/models.py like below. I know the last statement isn't defined. I'm not sure if it goes there or if I need to put it someplace else. Or if it does go there, how do I get "db" from the create_app() in init.py. I figure this has less to do with MongoKit and basic Python stuff.

/myapp/users/models.py

from flask.ext.mongokit import MongoKit, Document

class User(Document):
    structure = {
    'name': unicode,
    'email': unicode,
}
    use_dot_notation = True

db.register([User])
Was it helpful?

Solution

If you want to use create_app function, then I would change your __init__.py to something like:

/myapp/__init__.py

from flask import Flask, render_template, abort
from flask.ext.mongokit import MongoKit, Document

from .home.views import mod as home_blueprint
from .users.views import mod as user_blueprint
from .forums.views import mod as forum_blueprint

def create_app():
    app = Flask(__name__)
    app.config.from_object('config')

    # Register blueprints
    app.register_blueprint(home_blueprint)
    app.register_blueprint(user_blueprint, url_prefix="/users")
    app.register_blueprint(forum_blueprint, url_prefix="/forums")

    db = MongoKit(app)

    @app.errorhandler(404)
    def not_found(error):
        return render_template('404.html')

    @app.errorhandler(500)
    def internal_error(exception):
        return "Some internal error has taken place.  Alert somebody!"

    return app,db

# Make sure you are calling create_app func below:
(app,db) = create_app()

Now in your models code, you can refer to db variable.

/myapp/users/models.py

from flask.ext.mongokit import MongoKit, Document

# import db below like this
from myapp import db

class User(Document):
    structure = {
    'name': unicode,
    'email': unicode,
}
use_dot_notation = True

# ok to do this below
db.register([User])
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top