Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
flask-admin
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
JIRA
JIRA
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Python-Dev
flask-admin
Commits
512301a9
Commit
512301a9
authored
Oct 16, 2018
by
PJ Janse van Rensburg
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'nested-categories'
parents
108cbd75
259e6363
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
120 additions
and
157 deletions
+120
-157
introduction.rst
doc/introduction.rst
+25
-6
README.rst
examples/menu-external-links/README.rst
+0
-23
app.py
examples/menu-external-links/app.py
+0
-97
requirements.txt
examples/menu-external-links/requirements.txt
+0
-3
authenticated-admin.html
...es/menu-external-links/templates/authenticated-admin.html
+0
-4
app.py
examples/sqla/app.py
+6
-1
base.py
flask_admin/base.py
+22
-1
menu.py
flask_admin/menu.py
+7
-1
base.py
flask_admin/model/base.py
+1
-1
submenu.css
flask_admin/static/admin/css/bootstrap3/submenu.css
+18
-0
layout.html
flask_admin/templates/bootstrap2/admin/layout.html
+18
-10
base.html
flask_admin/templates/bootstrap3/admin/base.html
+1
-0
layout.html
flask_admin/templates/bootstrap3/admin/layout.html
+22
-10
No files found.
doc/introduction.rst
View file @
512301a9
...
...
@@ -156,12 +156,9 @@ Customizing Built-in Views
****
The built-in `ModelView` class is great for getting started quickly. But, you'll want
to configure its functionality to suit your particular models. This is done by setting
values for the configuration attributes that are made available in the `ModelView` class.
To specify some global configuration parameters, you can subclass `ModelView` and use that
subclass when adding your models to the interface::
When inheriting from `ModelView`, values can be specified for numerous
configuration parameters. Use these to customize the views to suit your
particular models::
from flask_admin.contrib.sqla import ModelView
...
...
@@ -287,6 +284,28 @@ To **enable csv export** of the model view::
This will add a button to the model view that exports records, truncating at :attr:`~flask_admin.model.BaseModelView.export_max_rows`.
Grouping Views
==============
When adding a view, specify a value for the `category` parameter
to group related views together in the menu::
admin.add_view(UserView(User, db.session, category="Team"))
admin.add_view(ModelView(Role, db.session, category="Team"))
admin.add_view(ModelView(Permission, db.session, category="Team"))
This will create a top-level menu item named 'Team', and a drop-down containing
links to the three views.
To nest related views within these drop-downs, use the `add_sub_category` method::
admin.add_sub_category(name="Links", parent_name="Team")
And to add arbitrary hyperlinks to the menu::
admin.add_link(MenuLink(name='Home Page', url='/', category='Links'))
Adding Your Own Views
=====================
...
...
examples/menu-external-links/README.rst
deleted
100644 → 0
View file @
108cbd75
This example shows how you can add links to external (non flask-admin) pages to the navbar menu, and how you can hide certain links if a user is not logged-in.
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/menu-external-links/requirements.txt'
4. Run the application::
python examples/menu-external-links/app.py
examples/menu-external-links/app.py
deleted
100644 → 0
View file @
108cbd75
from
flask
import
Flask
,
redirect
,
url_for
from
flask_login
import
current_user
,
UserMixin
,
login_user
,
logout_user
,
LoginManager
from
flask_admin.base
import
MenuLink
,
Admin
,
BaseView
,
expose
# Create fake user class for authentication
class
User
(
UserMixin
):
users_id
=
0
def
__init__
(
self
,
id
=
None
):
if
not
id
:
self
.
users_id
+=
1
self
.
id
=
self
.
users_id
else
:
self
.
id
=
id
# Create menu links classes with reloaded accessible
class
AuthenticatedMenuLink
(
MenuLink
):
def
is_accessible
(
self
):
return
current_user
.
is_authenticated
class
NotAuthenticatedMenuLink
(
MenuLink
):
def
is_accessible
(
self
):
return
not
current_user
.
is_authenticated
# Create custom admin view for authenticated users
class
MyAdminView
(
BaseView
):
@
expose
(
'/'
)
def
index
(
self
):
return
self
.
render
(
'authenticated-admin.html'
)
def
is_accessible
(
self
):
return
current_user
.
is_authenticated
# Create flask app
app
=
Flask
(
__name__
,
template_folder
=
'templates'
)
# Create dummy secrey key so we can use sessions
app
.
config
[
'SECRET_KEY'
]
=
'123456790'
# Flask views
@
app
.
route
(
'/'
)
def
index
():
return
'<a href="/admin/">Click me to get to Admin!</a>'
@
app
.
route
(
'/login/'
)
def
login_view
():
login_user
(
User
())
return
redirect
(
url_for
(
'admin.index'
))
@
app
.
route
(
'/logout/'
)
def
logout_view
():
logout_user
()
return
redirect
(
url_for
(
'admin.index'
))
login_manager
=
LoginManager
()
login_manager
.
init_app
(
app
)
# Create user loader function
@
login_manager
.
user_loader
def
load_user
(
user_id
):
return
User
(
user_id
)
if
__name__
==
'__main__'
:
# Create admin interface
admin
=
Admin
(
name
=
'Example: Menu'
)
admin
.
add_view
(
MyAdminView
(
name
=
'Authenticated'
))
# Add home link by url
admin
.
add_link
(
MenuLink
(
name
=
'Back Home'
,
url
=
'/'
))
# Add login link by endpoint
admin
.
add_link
(
NotAuthenticatedMenuLink
(
name
=
'Login'
,
endpoint
=
'login_view'
))
# Add links with categories
admin
.
add_link
(
MenuLink
(
name
=
'Google'
,
category
=
'Links'
,
url
=
'http://www.google.com/'
))
admin
.
add_link
(
MenuLink
(
name
=
'Mozilla'
,
category
=
'Links'
,
url
=
'http://mozilla.org/'
))
# Add logout link by endpoint
admin
.
add_link
(
AuthenticatedMenuLink
(
name
=
'Logout'
,
endpoint
=
'logout_view'
))
admin
.
init_app
(
app
)
# Start app
app
.
run
(
debug
=
True
)
examples/menu-external-links/requirements.txt
deleted
100644 → 0
View file @
108cbd75
Flask
Flask-Admin
Flask-Login>=0.3.0
examples/menu-external-links/templates/authenticated-admin.html
deleted
100644 → 0
View file @
108cbd75
{% extends 'admin/master.html' %}
{% block body %}
Hello World from Authenticated Admin!
{% endblock %}
examples/sqla/app.py
View file @
512301a9
...
...
@@ -8,6 +8,7 @@ from wtforms import validators
import
flask_admin
as
admin
from
flask_admin.contrib
import
sqla
from
flask_admin.contrib.sqla
import
filters
from
flask_admin.base
import
MenuLink
# Create application
...
...
@@ -163,7 +164,11 @@ admin = admin.Admin(app, name='Example: SQLAlchemy', template_mode='bootstrap3')
admin
.
add_view
(
UserAdmin
(
User
,
db
.
session
))
admin
.
add_view
(
sqla
.
ModelView
(
Tag
,
db
.
session
))
admin
.
add_view
(
PostAdmin
(
db
.
session
))
admin
.
add_view
(
TreeView
(
Tree
,
db
.
session
))
admin
.
add_view
(
TreeView
(
Tree
,
db
.
session
,
category
=
"Other"
))
admin
.
add_sub_category
(
name
=
"Links"
,
parent_name
=
"Other"
)
admin
.
add_link
(
MenuLink
(
name
=
'Back Home'
,
url
=
'/'
,
category
=
'Links'
))
admin
.
add_link
(
MenuLink
(
name
=
'Google'
,
url
=
'http://www.google.com/'
,
category
=
'Links'
))
admin
.
add_link
(
MenuLink
(
name
=
'Mozilla'
,
url
=
'http://mozilla.org/'
,
category
=
'Links'
))
def
build_sample_db
():
...
...
flask_admin/base.py
View file @
512301a9
...
...
@@ -9,7 +9,7 @@ from flask_admin._compat import with_metaclass, as_unicode
from
flask_admin
import
helpers
as
h
# For compatibility reasons import MenuLink
from
flask_admin.menu
import
MenuCategory
,
MenuView
,
MenuLink
# noqa: F401
from
flask_admin.menu
import
MenuCategory
,
MenuView
,
MenuLink
,
SubMenuCategory
# noqa: F401
def
expose
(
url
=
'/'
,
methods
=
(
'GET'
,)):
...
...
@@ -581,6 +581,27 @@ class Admin(object):
for
view
in
args
:
self
.
add_view
(
view
)
def
add_sub_category
(
self
,
name
,
parent_name
):
"""
Add a category of a given name underneath
the category with parent_name.
:param name:
The name of the new menu category.
:param parent_name:
The name of a parent_name category
"""
name_text
=
as_unicode
(
name
)
parent_name_text
=
as_unicode
(
parent_name
)
category
=
self
.
get_category_menu_item
(
name_text
)
parent
=
self
.
get_category_menu_item
(
parent_name_text
)
if
category
is
None
and
parent
is
not
None
:
category
=
SubMenuCategory
(
name
)
self
.
_menu_categories
[
name_text
]
=
category
parent
.
add_child
(
category
)
def
add_link
(
self
,
link
):
"""
Add link to menu links collection.
...
...
flask_admin/menu.py
View file @
512301a9
...
...
@@ -7,7 +7,7 @@ class BaseMenu(object):
"""
def
__init__
(
self
,
name
,
class_name
=
None
,
icon_type
=
None
,
icon_value
=
None
,
target
=
None
):
self
.
name
=
name
self
.
class_name
=
class_name
self
.
class_name
=
class_name
if
class_name
is
not
None
else
''
self
.
icon_type
=
icon_type
self
.
icon_value
=
icon_value
self
.
target
=
target
...
...
@@ -141,3 +141,9 @@ class MenuLink(BaseMenu):
def
get_url
(
self
):
return
self
.
url
or
url_for
(
self
.
endpoint
)
class
SubMenuCategory
(
MenuCategory
):
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
SubMenuCategory
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
self
.
class_name
+=
' dropdown-submenu'
flask_admin/model/base.py
View file @
512301a9
...
...
@@ -783,7 +783,7 @@ class BaseModelView(BaseView, ActionsMixin):
:param name:
View name. If not provided, will use the model class name
:param category:
View category
Optional category name, for grouping views in the menu
:param endpoint:
Base endpoint. If not provided, will use the model name.
:param url:
...
...
flask_admin/static/admin/css/bootstrap3/submenu.css
0 → 100644
View file @
512301a9
.nav
li
.dropdown
ul
.dropdown-menu
li
:hover
ul
{
display
:
block
;
position
:
absolute
;
left
:
100%
;
-webkit-border-radius
:
3px
;
-moz-border-radius
:
3px
;
border-radius
:
3px
;
}
.nav
li
.dropdown
ul
.dropdown-menu
ul
{
display
:
none
;
float
:
right
;
position
:
relative
;
top
:
auto
;
margin-top
:
-30px
;
}
.nav
li
.dropdown
a
.dropdown-toggle
.glyphicon
{
margin
:
0
4px
;
}
flask_admin/templates/bootstrap2/admin/layout.html
View file @
512301a9
...
...
@@ -20,25 +20,33 @@
{%- if item.is_category() -%}
{% set children = item.get_children() %}
{%- if children %}
{% set class_name = item.get_class_name() %}
{% set class_name = item.get_class_name()
or ''
%}
{%- if item.is_active(admin_view) %}
<li
class=
"active dropdown"
>
<li
class=
"active dropdown
{% if class_name %} {{class_name}}{% endif %}
"
>
{% else -%}
<li
class=
"dropdown"
>
<li
class=
"dropdown
{% if class_name %} {{class_name}}{% endif %}
"
>
{%- endif %}
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"javascript:void(0)"
>
{% if item.class_name %}
<i
class=
"{{ item.class_name }}"
></i>
{% endif %}{{ item.name }}
<b
class=
"caret"
></b>
{% if item.class_name %}
<i
class=
"{{ item.class_name }}"
></i>
{% endif %}
{{ menu_icon(item) }}{{ item.name }}
{%- if 'dropdown-submenu' not in class_name -%}
<b
class=
"caret"
></b>
{%- endif -%}
</a>
<ul
class=
"dropdown-menu"
>
{%- for child in children -%}
{% set class_name = child.get_class_name() %}
{%- if child.is_active(admin_view) %}
<li
class=
"active{% if class_name %} {{class_name}}{% endif %}"
>
{%- if child.is_category() -%}
{{ menu(menu_root=[child]) }}
{% else %}
<li
{%
if
class_name
%}
class=
"{{class_name}}"
{%
endif
%}
>
{% set class_name = child.get_class_name() %}
{%- if child.is_active(admin_view) %}
<li
class=
"active{% if class_name %} {{class_name}}{% endif %}"
>
{% else %}
<li
{%
if
class_name
%}
class=
"{{class_name}}"
{%
endif
%}
>
{%- endif %}
<a
href=
"{{ child.get_url() }}"
{%
if
child
.
target
%}
target=
"{{ child.target }}"
{%
endif
%}
>
{{ menu_icon(child) }}{{ child.name }}
</a>
</li>
{%- endif %}
<a
href=
"{{ child.get_url() }}"
{%
if
child
.
target
%}
target=
"{{ child.target }}"
{%
endif
%}
>
{{ menu_icon(child) }}{{ child.name }}
</a>
</li>
{%- endfor %}
</ul>
</li>
...
...
flask_admin/templates/bootstrap3/admin/base.html
View file @
512301a9
...
...
@@ -17,6 +17,7 @@
<link
href=
"{{ admin_static.url(filename='bootstrap/bootstrap3/css/bootstrap-theme.min.css', v='3.3.5') }}"
rel=
"stylesheet"
>
{%endif%}
<link
href=
"{{ admin_static.url(filename='admin/css/bootstrap3/admin.css', v='1.1.1') }}"
rel=
"stylesheet"
>
<link
href=
"{{ admin_static.url(filename='admin/css/bootstrap3/submenu.css') }}"
rel=
"stylesheet"
>
{% if admin_view.extra_css %}
{% for css_url in admin_view.extra_css %}
<link
href=
"{{ css_url }}"
rel=
"stylesheet"
>
...
...
flask_admin/templates/bootstrap3/admin/layout.html
View file @
512301a9
...
...
@@ -20,25 +20,37 @@
{%- if item.is_category() -%}
{% set children = item.get_children() %}
{%- if children %}
{% set class_name = item.get_class_name() %}
{% set class_name = item.get_class_name()
or ''
%}
{%- if item.is_active(admin_view) %}
<li
class=
"active dropdown"
>
<li
class=
"active dropdown
{% if class_name %} {{class_name}}{% endif %}
"
>
{% else -%}
<li
class=
"dropdown"
>
<li
class=
"dropdown
{% if class_name %} {{class_name}}{% endif %}
"
>
{%- endif %}
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"javascript:void(0)"
>
{% if item.class_name %}
<span
class=
"{{ item.class_name }}"
></span>
{% endif %}{{ item.name }}
<b
class=
"caret"
></b>
{% if item.class_name %}
<span
class=
"{{ item.class_name }}"
></span>
{% endif %}
{{ menu_icon(item) }}{{ item.name }}
{%- if 'dropdown-submenu' in class_name -%}
<i
class=
"glyphicon glyphicon-chevron-right small"
></i>
{%- else -%}
<i
class=
"glyphicon glyphicon-chevron-down small"
></i>
{%- endif -%}
</a>
<ul
class=
"dropdown-menu"
>
{%- for child in children -%}
{% set class_name = child.get_class_name() %}
{%- if child.is_active(admin_view) %}
<li
class=
"active{% if class_name %} {{class_name}}{% endif %}"
>
{%- if child.is_category() -%}
{{ menu(menu_root=[child]) }}
{% else %}
<li
{%
if
class_name
%}
class=
"{{class_name}}"
{%
endif
%}
>
{% set class_name = child.get_class_name() %}
{%- if child.is_active(admin_view) %}
<li
class=
"active{% if class_name %} {{class_name}}{% endif %}"
>
{% else %}
<li
{%
if
class_name
%}
class=
"{{class_name}}"
{%
endif
%}
>
{%- endif %}
<a
href=
"{{ child.get_url() }}"
{%
if
child
.
target
%}
target=
"{{ child.target }}"
{%
endif
%}
>
{{ menu_icon(child) }}{{ child.name }}
</a>
</li>
{%- endif %}
<a
href=
"{{ child.get_url() }}"
{%
if
child
.
target
%}
target=
"{{ child.target }}"
{%
endif
%}
>
{{ menu_icon(child) }}{{ child.name }}
</a>
</li>
{%- endfor %}
</ul>
</li>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment