MongoEngine flask extension with WTF model forms support
Switch branches/tags
Nothing to show
Pull request Compare This branch is 483 commits behind MongoEngine:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



A Flask extension that provides integration with MongoEngine. It handles connection management for your app.

You can also use WTForms as model forms for your models.

Installing Flask-MongoEngine

Install with pip:

pip install


Basic setup is easy, just fetch the extension:

from flask import Flask
from flaskext.mongoengine import MongoEngine

app = Flask(__name__)
db = MongoEngine(app)

Custom Queryset

To get get_or_404, first_or_404 or paginate you need to declare the queryset in your model meta like so:

class Todo(db.Document):
    title = db.StringField(max_length=60)
    text = db.StringField()
    done = db.BooleanField(default=False)
    pub_date = db.DateTimeField(

    meta = dict(queryset_class=db.QuerySet)

The you can do things like:

# 404 if not exists
def view_todo(todo_id):
    todo = Todo.objects.get_or_404(_id=todo_id)

# Paginate through todo
def view_todos(page=1):
    page = Todo.objects.paginate(page=page, per_page=10)

In the template:

{% macro render_pagination(pagination, endpoint) %}
  <div class=pagination>
  {%- for page in pagination.iter_pages() %}
    {% if page %}
      {% if page != %}
        <a href="{{ url_for(endpoint, page=page) }}">{{ page }}</a>
      {% else %}
        <strong>{{ page }}</strong>
      {% endif %}
    {% else %}
      <span class=ellipsis>…</span>
    {% endif %}
  {%- endfor %}
{% endmacro %}

MongoEngine and WTForms

You can use MongoEngine and WTForms like so:

from import model_form

class User(db.Document):
    email = db.StringField(required=True)
    first_name = db.StringField(max_length=50)
    last_name = db.StringField(max_length=50)

class Content(db.EmbeddedDocument):
    text = db.StringField()
    lang = db.StringField(max_length=3)

class Post(Document):
    title = db.StringField(max_length=120, required=True)
    author = db.ReferenceField(User)
    tags = db.ListField(StringField(max_length=30))
    content = db.EmbeddedDocumentField(Content)

PostForm = model_form(Post)

def add_post(request):
    form = PostForm(request.POST)
    if request.method == 'POST' and form.validate():
        # do something
    return render_response('add_post.html', form=form)

Supported fields

  • StringField
  • BinaryField
  • URLField
  • EmailField
  • IntField
  • FloatField
  • DecimalField
  • BooleanField
  • DateTimeField
  • ListField (using wtforms.fields.FieldList )
  • SortedListField (duplicate ListField)
  • EmbeddedDocumentField (using wtforms.fields.FormField and generating inline Form)
  • ReferenceField (using wtforms.fields.SelectFieldBase with options loaded from QuerySet or Document)
  • DictField

Not currently supported field types:

  • ObjectIdField
  • GeoLocationField
  • GenericReferenceField


Inspired by two repos:

danjac maratfm