MongoEngine flask extension with WTF model forms support
Python Shell
Switch branches/tags
Nothing to show
Pull request Compare This branch is 473 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

flask-mongoengine attaches the following methods to Mongoengine's default QuerySet:

  • get_or_404: works like .get(), but calls abort(404) if the object DoesNotExist.
  • first_or_404: same as above, except for .first().
  • paginate: paginates the QuerySet. Takes two arguments, page and per_page.
  • paginate_field: paginates a field from one document in the QuerySet. Arguments: field_name, doc_id, page, per_page.


# 404 if object doesn't exist
def view_todo(todo_id):
    todo = Todo.objects.get_or_404(_id=todo_id)

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

# Paginate through tags of todo
def view_todo_tags(page=1):
    todo_id = Todo.objects.first().id
    paginated_tags = Todo.objects.paginate_field('tags', todo_id, page,

Properties of the pagination object include: iter_pages, next, prev, has_next, has_prev, next_num, prev_num.

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)

Debug Toolbar Panels

There are two panels for the flask-debugtoolbar included with flask-mongoengine. Both of them contain information about the MongoDB operations made by your app, although they work in different ways.

Both of them track the time operations take, how many items had to be scanned, the query parameters and the collection being accessed, amongst other things. The key difference to the end user is that MongoDebugPanel records where the query was made from in your codebase.

MongoenginePanel uses MongoDB's in-built system profiler to track operations. It supports 2.0's overhaul of the profiler.

MongoDebugPanel (adapted from works by monkey-patching PyMongo's operation functions (insert, update, etc.). It tries to identify where the query originated, and shows the relevant stacktrace (with line numbers, filenames, etc.). At the moment, it can't do this for queries made from templates.


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