Skip to content
Merged
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
12 changes: 5 additions & 7 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,18 @@ on:
- '*.rst'
jobs:
tests:
name: ${{ matrix.tox == 'normal' && format('py{0}-flask{1}-wtforms{2}', matrix.python, matrix.flask, matrix.wtforms) || matrix.tox }}
name: ${{ matrix.tox == 'normal' && format('py{0}', matrix.python) || matrix.tox }}
runs-on: ${{ matrix.os || 'ubuntu-latest' }}
strategy:
fail-fast: false
matrix:
python: ['3.8', '3.9', '3.10', '3.11', '3.12']
flask: ['2']
wtforms: ['2']
tox: ['normal']
include:
- python: '3.12'
flask: '2'
wtforms: '2'
tox: 'py312-flask2-wtforms2-no-flask-babel'
tox: 'py312-noflaskbabel'
- python: '3.12'
tox: 'py312-flaskmongoengine'
services:
# Label used to access the service container
postgres:
Expand Down Expand Up @@ -75,7 +73,7 @@ jobs:
PGPASSWORD: postgres
run: psql -U postgres -h localhost -c 'CREATE EXTENSION hstore;' flask_admin_test
- run: pip install tox
- run: tox run -e ${{ matrix.tox == 'normal' && format('py{0}-flask{1}-wtforms{2}', matrix.python, matrix.flask, matrix.wtforms) || matrix.tox }}
- run: tox run -e ${{ matrix.tox == 'normal' && format('py{0}', matrix.python) || matrix.tox }}
not_tests:
name: ${{ matrix.tox }}
runs-on: ubuntu-latest
Expand Down
46 changes: 38 additions & 8 deletions doc/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,40 @@ Introduction To Flask-Admin
Getting Started
===============

****
Installing Flask-Admin
----------------------

Flask-Admin provides an easy-to-use layer on top of a number of databases and file stores.
Whether you use SQLAlchemy, peewee, AWS S3, or something else that Flask-Admin supports,
we don't install those things out-of-the-box. This reduces the risk of compatibility issues
and means that you don't download/install anything you don't need.

Depending on what you use, you should install Flask-Admin with your required extras selected.

Flask-Admin has these optional extras you can select:

=========================== ================================================
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
appengine Supports Google's appengine library
s3 Supports file admin using AWS S3
azure-blob-storage Supports file admin using Azure blob store
images Allows working with image data
export Supports downloading data in a variety of formats (eg TSV, JSON, etc)
rediscli Allows Flask-Admin to display a CLI for Redis
translation Supports translating Flask-Admin into a number of languages
all Installs support for all features
=========================== ================================================

Once you've chosen the extras you need, install Flask-Admin by specifying them like so::

pip install flask-admin[sqlalchemy,s3,images,export,translation]

Initialization
--------------
Expand Down Expand Up @@ -73,8 +106,6 @@ So, now you can add any content to the index page, while maintaining a consisten
Authorization & Permissions
===========================

****

When setting up an admin interface for your application, one of the first problems
you'll want to solve is how to keep unwanted users out. With Flask-Admin there
are a few different ways of approaching this.
Expand Down Expand Up @@ -310,8 +341,6 @@ And to add arbitrary hyperlinks to the menu::
Adding Your Own Views
=====================

****

For situations where your requirements are really specific and you struggle to meet
them with the built-in :class:`~flask_admin.model.ModelView` class, Flask-Admin makes it easy for you to
take full control and add your own views to the interface.
Expand Down Expand Up @@ -467,17 +496,18 @@ empty_list_message Message that will be displayed if there are no models fo
Have a look at the `layout` example at https://github.com/flask-admin/flask-admin/tree/master/examples/custom-layout
to see how you can take full stylistic control over the admin interface.

Environment Variables
---------------------
Template Context Variables
--------------------------

While working in any of the templates that extend `admin/master.html`, you have access to a small number of
environment variables:
context variables:

==================== ================================
Variable Name Description
==================== ================================
admin_view Current administrative view
admin_base_template Base template name
theme The Theme configuration passed into Flask-Admin at instantiation
_gettext Babel gettext
_ngettext Babel ngettext
h Helpers from :mod:`~flask_admin.helpers` module
Expand Down
6 changes: 3 additions & 3 deletions examples/auth-flask-login/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Flask
Flask-Admin
Flask-SQLAlchemy
# Install Flask-Admin with required extras from the root of the repository
../..[sqlalchemy]

Flask-Login>=0.3.0
6 changes: 3 additions & 3 deletions examples/auth-mongoengine/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Flask
Flask-Admin
flask-mongoengine
# Install Flask-Admin with required extras from the root of the repository
../..[mongoengine]

Flask-Login>=0.3.0
7 changes: 3 additions & 4 deletions examples/auth/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
Flask
Flask-Admin
Flask-SQLAlchemy
# Install Flask-Admin with required extras from the root of the repository
../..[sqlalchemy-with-utils]

flask-security-too
email_validator
6 changes: 2 additions & 4 deletions examples/babel/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
Flask
Flask-Admin
Flask-SQLAlchemy
Flask-Babel
# Install Flask-Admin with required extras from the root of the repository
../..[sqlalchemy,translation]
5 changes: 2 additions & 3 deletions examples/bootstrap4/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
Flask
Flask-Admin
Flask-SQLAlchemy
# Install Flask-Admin with required extras from the root of the repository
../..[sqlalchemy]
5 changes: 2 additions & 3 deletions examples/custom-layout/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
Flask
Flask-Admin
Flask-SQLAlchemy
# Install Flask-Admin with required extras from the root of the repository
../..[sqlalchemy]
7 changes: 2 additions & 5 deletions examples/forms-files-images/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
Flask
Flask-Admin
Flask-SQLAlchemy
pillow
redis
# Install Flask-Admin with required extras from the root of the repository
../..[sqlalchemy,images,rediscli]
2 changes: 0 additions & 2 deletions examples/geo_alchemy/app.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from flask import Flask
from flask_babel import Babel
from flask_sqlalchemy import SQLAlchemy

import flask_admin as admin
Expand All @@ -11,7 +10,6 @@

# Create application
app = Flask(__name__)
babel = Babel(app)
app.config.from_pyfile('config.py')
db = SQLAlchemy(app)

Expand Down
10 changes: 4 additions & 6 deletions examples/geo_alchemy/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
Flask
Flask-Admin
Flask-SQLAlchemy
shapely
geoalchemy2
psycopg2
# Install Flask-Admin with required extras from the root of the repository
../..[sqlalchemy,geoalchemy]

psycopg2
3 changes: 1 addition & 2 deletions examples/host-matching/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
Flask
Flask-Admin
../..
3 changes: 1 addition & 2 deletions examples/methodview/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
Flask
Flask-Admin
../..
7 changes: 2 additions & 5 deletions examples/mongoengine/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
Flask
Flask-Admin
Flask-MongoEngine
../..[mongoengine,images]

Flask-Login>=0.3.0
Pillow
sqlalchemy
3 changes: 1 addition & 2 deletions examples/multiple-admin-instances/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
Flask
Flask-Admin
../..
6 changes: 1 addition & 5 deletions examples/peewee/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
Flask
Flask-Admin
peewee
wtf-peewee
sqlalchemy
../..[peewee]
4 changes: 1 addition & 3 deletions examples/pymongo/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
Flask
Flask-Admin
pymongo
../..[pymongo]
3 changes: 1 addition & 2 deletions examples/simple/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
Flask
Flask-Admin
../..
4 changes: 1 addition & 3 deletions examples/sqla-association_proxy/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
Flask
Flask-Admin
Flask-SQLAlchemy
../..[sqlalchemy]
5 changes: 1 addition & 4 deletions examples/sqla-custom-inline-forms/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
Flask
Flask-Admin
Flask-SQLAlchemy
WTForms
../..[sqlalchemy]
3 changes: 2 additions & 1 deletion examples/sqla/admin/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from admin import app, db
from admin.models import AVAILABLE_USER_TYPES, User, Post, Tag, Tree
from flask import Markup, send_file
from flask import send_file
from markupsafe import Markup

from wtforms import validators

Expand Down
16 changes: 2 additions & 14 deletions examples/sqla/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,2 @@
Flask
Flask-Admin
Flask-Babel
Flask-SQLAlchemy
tablib
enum34; python_version < '3.0'
sqlalchemy_utils
arrow
colour
email_validator

# note: for local development, replace 'Flask-Admin' above with a reference to
# your local copy of the repo e.g. '-e .' if you're installing this from the
# repo's root directory
# Install Flask-Admin with required extras from the root of the repository
../..[sqlalchemy-with-utils,export,translation]
5 changes: 2 additions & 3 deletions examples/tinymongo/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
Flask
Flask-Admin
pymongo==2.5.2
../..[pymongo]

git+https://github.com/schapman1974/tinymongo.git#egg=tinymongo
5 changes: 4 additions & 1 deletion flask_admin/contrib/appengine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
try:
import wtforms_appengine
except ImportError:
raise Exception('Please install wtforms_appengine in order to use appengine backend')
raise Exception(
'Could not import `wtforms-appengine`. '
'Enable `appengine` integration by installing `flask-admin[appengine]`'
)

from .view import ModelView
8 changes: 5 additions & 3 deletions flask_admin/contrib/fileadmin/azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ def __init__(self, container_name, connection_string):
"""

if not BlockBlobService:
raise ValueError('Could not import Azure Blob Storage SDK. '
'You can install the SDK using '
'pip install azure-storage-blob')
raise ValueError(
'Could not import `azure.storage.blob`. '
'Enable `azure-blob-storage` integration '
'by installing `flask-admin[azure-blob-storage]`'
)

self._container_name = container_name
self._connection_string = connection_string
Expand Down
6 changes: 4 additions & 2 deletions flask_admin/contrib/fileadmin/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ def __init__(self, bucket_name, region, aws_access_key_id,
"""

if not s3:
raise ValueError('Could not import boto. You can install boto by '
'using pip install boto')
raise ValueError(
'Could not import `boto`. '
'Enable `s3` integration by installing `flask-admin[s3]`'
)

connection = s3.connect_to_region(
region,
Expand Down
5 changes: 4 additions & 1 deletion flask_admin/contrib/geoa/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import geoalchemy2
import shapely
except ImportError:
raise Exception('Please install geoalchemy2 and shapely in order to use geoalchemy integration')
raise Exception(
'Could not import `geoalchemy2` or `shapely`. '
'Enable `geoalchemy` integration by installing `flask-admin[geoalchemy]`'
)

from .view import ModelView
5 changes: 4 additions & 1 deletion flask_admin/contrib/mongoengine/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
try:
import flask_mongoengine
except ImportError:
raise Exception('Please install flask-mongoengine in order to use mongoengine backend')
raise Exception(
'Could not import `flask-mongoengine`. '
'Enable `mongoengine` integration by installing `flask-admin[mongoengine]`'
)

from .view import ModelView
from .form import EmbeddedForm
5 changes: 4 additions & 1 deletion flask_admin/contrib/peewee/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import peewee
import wtfpeewee
except ImportError:
raise Exception('Please install peewee and wtf-peewee packages in order to use peewee integration')
raise Exception(
'Could not import `peewee` or `wtfpeewee`. '
'Enable `peewee` integration by installing `flask-admin[peewee]`'
)

from .view import ModelView
5 changes: 4 additions & 1 deletion flask_admin/contrib/pymongo/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
try:
import pymongo
except ImportError:
raise Exception('Please install pymongo in order to use pymongo integration')
raise Exception(
'Could not import `pymongo`. '
'Enable `pymongo` integration by installing `flask-admin[pymongo]`'
)

from .view import ModelView
5 changes: 4 additions & 1 deletion flask_admin/form/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,10 @@ class MyForm(BaseForm):
"""
# Check if PIL is installed
if Image is None:
raise ImportError('PIL library was not found')
raise Exception(
'Could not import `PIL`. '
'Enable `images` integration by installing `flask-admin[images]`'
)

self.max_size = max_size
self.thumbnail_fn = thumbgen or thumbgen_filename
Expand Down
6 changes: 4 additions & 2 deletions flask_admin/model/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2356,8 +2356,10 @@ def _export_tablib(self, export_type, return_url):
Exports a variety of formats using the tablib library.
"""
if tablib is None:
flash(gettext('Tablib dependency not installed.'), 'error')
return redirect(return_url)
raise Exception(
'Could not import `tablib`. '
'Enable `export` integration by installing `flask-admin[export]`'
)

filename = self.get_export_name(export_type)

Expand Down
4 changes: 2 additions & 2 deletions flask_admin/tests/fileadmin/test_fileadmin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from io import StringIO
from io import BytesIO
import os
import os.path as op

Expand Down Expand Up @@ -71,7 +71,7 @@ class MyFileAdmin(fileadmin_class):
assert rv.status_code == 200

rv = client.post('/admin/myfileadmin/upload/',
data=dict(upload=(StringIO(""), 'dummy.txt')))
data=dict(upload=(BytesIO(b""), 'dummy.txt')))
assert rv.status_code == 302

rv = client.get('/admin/myfileadmin/')
Expand Down
Loading