4

How do I handle and reference multiple models in a Flask application?

Is there any reason I cannot have more than one model class, .py files? Instead of one big models.py, is there a way to have the following in flask:

Example models:

students.py
teachers.py
classes.py
schedules.py
...

?

2 Answers 2

10

This is a flask app I wanted to structure like Django:

/blog_project
    config.py
    wsgi.py
    .gitignore
    /blog_app
        __init__.py # where factory application resides 
        /users
            /static
            /templates
            __init__.py
            models.py
            routes.py
            views.py
       /posts
            /static
            /templates
            __init__.py
            models.py
            routes.py
            views.py

I have attempted to structure my flask app in a manner similar to a Django project because my app became too unwieldy and difficult to maintain. I have a Factory Application function that creates the Flask app object which are registered with Flask Blueprints.

# users/routes.py

# import 
from Flask import Blueprint
from users.views import get_users

# Create Flask Blueprint object
user_pb = Blueprint(
    'user_pb',
    __name__,
    template_folder='templates',
    static_folder='strains/static'
)

@user_bp.route('/users', methods=['GET'])
def users():
    return get_users()
# posts/routes.py

# import 
from Flask import Blueprint
from users.posts import get_posts

# Create Flask Blueprint object
post_pb = Blueprint(
    'post_pb',
    __name__,
    template_folder='templates',
    static_folder='strains/static'
)

@user_bp.route('/posts', methods=['GET'])
def posts():
    return get_posts()


# posts/models.py

# import sql-alchemy db instance created with factory application
from blog_app import db


class Post(db.Model):
    """
    A simple model with a string based column 'content'.
    """
    id = db.Column(db.Integer, primary_key=True)
    content = db.Column(db.String(96), nullable=False)

    def __repr__(self):
        return f"post id: {self.id}"
# users/models.py

# import sql-alchemy db instance created with factory application
from blog_app import db


class User(db.Model):
    """
    A simple model with a string based column 'name'.
    """
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(96), nullable=False)

    def __repr__(self):
        return f"post id: {self.name}"

These blueprints are objects that help keep your routes modular and how I was able to create the User and Post packages, which contain all the modules related to a specific part of the app. For instance, the packages will have the models, url routes which will connect with views, and finally the templates to render the dynamic HTML.

The flask app object is created with the application factory function found in blog_app/__init__.py:

# blog_app/__init__.py

# Import package dependencies

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

# Global libraries
db = SQLAlchemy()
migrate = Migrate()


def create_app():
    """Initialize core application."""
    app = Flask(__name__, instance_relative_config=False)
   """
    Configure application from Config class in project-level 
    config.py module.
   """

    app.config.from_object('yourconfig.Config')

    # Initialize plugins
    db.init_app(app)
    migrate.init_app(app, db)

    with app.app_context():
        from blog_app.posts import routes as posts_routes
        from blog_app.users import routes as users_routes

        # Register Blueprints
        app.register_blueprint(posts_routes.post_bp)
        app.register_blueprint(users_routes.user_bp)

    return app

To access a route from a template:

<a href="{{ url_for('posts_bp.posts') }}">Posts</a>
Sign up to request clarification or add additional context in comments.

1 Comment

I do not understand where do you run this create_app function..
2

Yes, you can use multiple modules for your models. Nothing in Flask or Python limits you to a specific module name or to just one module.

If you are using Flask-SQLAlchemy, just make sure you import the db object (the SQLAlchemy instance that defines the Model object) in each.

When you want to use a model, simply import it from the right module:

from students import Student
# etc.

If you are creating references between models, or want to use the create_all() function then at some point you'll need to have imported all models. Adding each module with a model to your main module would ensure this happens.

2 Comments

How do I reference them? Do I need an init.py in each model folder? Do you have an example (for one app only)? I can't find anything (hardly) where this is done in Flask.
@johnny: just import each model from their respective module when you need it. __init__.py files are for packages. You could put all the model modules into one models package if you so wish. That's all just standard Python however.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.