Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ application.
Out-of-the-box, Flask-Admin plays nicely with various ORM\'s, including

- [SQLAlchemy](https://www.sqlalchemy.org/)
- [MongoEngine](http://mongoengine.org/)
- [pymongo](https://pymongo.readthedocs.io/)
- and [Peewee](https://github.com/coleifer/peewee).

Expand Down
30 changes: 29 additions & 1 deletion doc/advanced.rst
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,8 @@ installed if you need to do any processing on the image files.
Have a look at the example at
https://github.com/pallets-eco/flask-admin/tree/master/examples/forms-files-images.

If you are using the MongoEngine backend, Flask-Admin supports GridFS-backed image and file uploads through WTForms fields. Documentation can be found at :mod:`flask_admin.contrib.mongoengine.fields`.

If you just want to manage static files in a directory, without tying them to a database model, then
use the :ref:`File-Admin<file-admin>` plug-in.

Expand Down Expand Up @@ -445,6 +447,32 @@ a model that violates a unique-constraint leads to an Sqlalchemy-Integrity-Error
a proper error message and you can change the data in the form. When the application has been started with ``debug=True``
the ``werkzeug`` debugger will catch the exception and will display the stacktrace.

MongoEngine
***********

If you're looking for something simpler than SQLAlchemy, and your data models
are reasonably self-contained, then `MongoDB <https://www.mongodb.org/>`_, a popular *NoSQL* database,
could be a better option.

`MongoEngine <http://mongoengine.org/>`_ is a python wrapper for MongoDB.
For an example of using MongoEngine with Flask-Admin, see
https://github.com/flask-admin/flask-admin/tree/master/examples/mongoengine.


Features:

- MongoEngine 0.7+ support
- Paging, sorting, filters, etc
- Supports complex document structure (lists, subdocuments and so on)
- GridFS support for file and image uploads

Known issues:

- Search functionality can't split query into multiple terms due to
MongoEngine query language limitations

For more, check the :class:`~flask_admin.contrib.mongoengine` API documentation.

Peewee
******

Expand Down Expand Up @@ -521,7 +549,7 @@ though it is easy to get started with a simple `CRUD <https://en.wikipedia.org/w
interface for each model in your application, Flask-Admin doesn't fix you to this approach, and you are free to
define other ways of interacting with some, or all, of your models.

Due to Flask-Admin supporting more than one ORM (SQLAlchemy, Peewee, raw pymongo), the developer is even
Due to Flask-Admin supporting more than one ORM (SQLAlchemy, MongoEngine, Peewee, raw pymongo), the developer is even
free to mix different model types into one application by instantiating appropriate CRUD classes.

Here is a list of some of the configuration properties that are made available by Flask-Admin and the
Expand Down
2 changes: 2 additions & 0 deletions doc/api/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ API

mod_contrib_sqla
mod_contrib_sqla_fields
mod_contrib_mongoengine
mod_contrib_mongoengine_fields
mod_contrib_peewee
mod_contrib_pymongo
mod_contrib_fileadmin
Expand Down
22 changes: 22 additions & 0 deletions doc/api/mod_contrib_mongoengine.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
``flask_admin.contrib.mongoengine``
===================================

MongoEngine model backend implementation.

.. automodule:: flask_admin.contrib.mongoengine

.. autoclass:: ModelView
:members:
:inherited-members:
:exclude-members: column_filters, column_type_formatters,
filter_converter, model_form_converter
allowed_search_types, form_subdocuments

Class inherits configuration options from :class:`~flask_admin.model.BaseModelView` and they're not displayed here.

.. autoattribute:: column_filters
.. autoattribute:: column_type_formatters
.. autoattribute:: filter_converter
.. autoattribute:: model_form_converter
.. autoattribute:: allowed_search_types
.. autoattribute:: form_subdocuments
13 changes: 13 additions & 0 deletions doc/api/mod_contrib_mongoengine_fields.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
``flask_admin.contrib.mongoengine.fields``
==========================================

.. automodule:: flask_admin.contrib.mongoengine.fields

.. autoclass:: ModelFormField
:members:

.. autoclass:: MongoFileField
:members:

.. autoclass:: MongoImageField
:members:
1 change: 1 addition & 0 deletions doc/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Extra name What functionality does this add to Flask-Admin?
sqlalchemy SQLAlchemy, for accessing many database engines
sqlalchemy-with-utils As above, with some additional utilities for different data types
geoalchemy As with SQLAlchemy, but adding support for geographic data and maps
mongoengine Supports the Flask-Mongoengine library
pymongo Supports the PyMongo library
peewee Supports the peewee library
s3 Supports file admin using AWS S3
Expand Down
23 changes: 23 additions & 0 deletions examples/auth-mongoengine/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
This example shows how to integrate Flask-Login authentication with Flask-Admin using the MongoEngine backend.

To run this example:

1. Clone the repository::

git clone https://github.com/flask-admin/flask-admin.git
cd flask-admin

2. Create and activate a virtual environment::

virtualenv env
source env/bin/activate

3. Install requirements::

pip install -r 'examples/auth-mongoengine/requirements.txt'

4. Run the application::

python examples/auth-mongoengine/app.py


151 changes: 151 additions & 0 deletions examples/auth-mongoengine/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
from flask import Flask, url_for, redirect, render_template, request
from flask_mongoengine import MongoEngine

from wtforms import form, fields, validators

import flask_admin as admin
import flask_login as login
from flask_admin.contrib.mongoengine import ModelView

# Create application
app = Flask(__name__)

# Create dummy secrey key so we can use sessions
app.config['SECRET_KEY'] = '123456790'

# MongoDB settings
app.config['MONGODB_SETTINGS'] = {'DB': 'test'}
db = MongoEngine()
db.init_app(app)


# Create user model. For simplicity, it will store passwords in plain text.
# Obviously that's not right thing to do in real world application.
class User(db.Document):
login = db.StringField(max_length=80, unique=True)
email = db.StringField(max_length=120)
password = db.StringField(max_length=64)

# Flask-Login integration
# NOTE: is_authenticated, is_active, and is_anonymous
# are methods in Flask-Login < 0.3.0
@property
def is_authenticated(self):
return True

@property
def is_active(self):
return True

@property
def is_anonymous(self):
return False

def get_id(self):
return str(self.id)

# Required for administrative interface
def __unicode__(self):
return self.login


# Define login and registration forms (for flask-login)
class LoginForm(form.Form):
login = fields.StringField(validators=[validators.InputRequired()])
password = fields.PasswordField(validators=[validators.InputRequired()])

def validate_login(self, field):
user = self.get_user()

if user is None:
raise validators.ValidationError('Invalid user')

if user.password != self.password.data:
raise validators.ValidationError('Invalid password')

def get_user(self):
return User.objects(login=self.login.data).first()


class RegistrationForm(form.Form):
login = fields.StringField(validators=[validators.InputRequired()])
email = fields.StringField()
password = fields.PasswordField(validators=[validators.InputRequired()])

def validate_login(self, field):
if User.objects(login=self.login.data):
raise validators.ValidationError('Duplicate username')


# Initialize flask-login
def init_login():
login_manager = login.LoginManager()
login_manager.setup_app(app)

# Create user loader function
@login_manager.user_loader
def load_user(user_id):
return User.objects(id=user_id).first()


# Create customized model view class
class MyModelView(ModelView):
def is_accessible(self):
return login.current_user.is_authenticated


# Create customized index view class
class MyAdminIndexView(admin.AdminIndexView):
def is_accessible(self):
return login.current_user.is_authenticated


# Flask views
@app.route('/')
def index():
return render_template('index.html', user=login.current_user)


@app.route('/login/', methods=('GET', 'POST'))
def login_view():
form = LoginForm(request.form)
if request.method == 'POST' and form.validate():
user = form.get_user()
login.login_user(user)
return redirect(url_for('index'))

return render_template('form.html', form=form)


@app.route('/register/', methods=('GET', 'POST'))
def register_view():
form = RegistrationForm(request.form)
if request.method == 'POST' and form.validate():
user = User()

form.populate_obj(user)
user.save()

login.login_user(user)
return redirect(url_for('index'))

return render_template('form.html', form=form)


@app.route('/logout/')
def logout_view():
login.logout_user()
return redirect(url_for('index'))

if __name__ == '__main__':
# Initialize flask-login
init_login()

# Create admin
admin = admin.Admin(app, 'Example: Auth-Mongo', index_view=MyAdminIndexView())

# Add view
admin.add_view(MyModelView(User))

# Start app
app.run(debug=True)
4 changes: 4 additions & 0 deletions examples/auth-mongoengine/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Install Flask-Admin with required extras from the root of the repository
../..[mongoengine]

Flask-Login>=0.3.0
21 changes: 21 additions & 0 deletions examples/auth-mongoengine/templates/form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<html>
<body>
<form method="POST" action="">
{{ form.hidden_tag() if form.hidden_tag }}
{% for f in form if f.type != 'CSRFTokenField' %}
<div>
{{ f.label }}
{{ f }}
{% if f.errors %}
<ul>
{% for e in f.errors %}
<li>{{ e }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endfor %}
<input type="submit" />
</form>
</body>
</html>
15 changes: 15 additions & 0 deletions examples/auth-mongoengine/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<html>
<body>
<div>
{% if user and user.is_authenticated %}
Hello {{ user.login }}! <a href="{{ url_for('logout_view') }}">Logout</a>
{% else %}
Welcome anonymous user!
<a href="{{ url_for('login_view') }}">Login</a>&nbsp;<a href="{{ url_for('register_view') }}">Register</a>
{% endif %}
</div>
<div>
<a href="{{ url_for('admin.index') }}">Go to admin!</a>
</div>
</body>
</html>
22 changes: 22 additions & 0 deletions examples/mongoengine/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
MongoEngine model backend integration.

To run this example:

1. Clone the repository::

git clone https://github.com/flask-admin/flask-admin.git
cd flask-admin

2. Create and activate a virtual environment::

virtualenv env
source env/bin/activate

3. Install requirements::

pip install -r 'examples/mongoengine/requirements.txt'

4. Run the application::

python examples/mongoengine/app.py

Loading
Loading