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
373448cb
Commit
373448cb
authored
Aug 19, 2012
by
mrjoes
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Separated actions from model admin
parent
73256448
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
164 additions
and
88 deletions
+164
-88
actions.py
flask_admin/actions.py
+80
-0
action.py
flask_admin/model/action.py
+0
-19
base.py
flask_admin/model/base.py
+6
-42
actions.js
flask_admin/static/js/actions.js
+36
-0
actions.html
flask_admin/templates/admin/actions.html
+33
-0
list.html
flask_admin/templates/admin/model/list.html
+9
-27
No files found.
flask_admin/actions.py
0 → 100644
View file @
373448cb
from
flask
import
request
,
url_for
,
redirect
def
action
(
name
,
text
,
confirmation
=
None
):
"""
Use this decorator to expose mass-model actions
`name`
Action name
`text`
Action text.
Will be passed through gettext() before rendering.
`confirmation`
Confirmation text. If not provided, action will be executed
unconditionally.
Will be passed through gettext() before rendering.
"""
def
wrap
(
f
):
f
.
_action
=
(
name
,
text
,
confirmation
)
return
f
return
wrap
class
ActionsMixin
(
object
):
def
__init__
(
self
):
self
.
_actions
=
[]
self
.
_actions_data
=
{}
def
init_actions
(
self
):
self
.
_actions
=
[]
self
.
_actions_data
=
{}
for
p
in
dir
(
self
):
attr
=
getattr
(
self
,
p
)
if
hasattr
(
attr
,
'_action'
):
name
,
text
,
desc
=
attr
.
_action
self
.
_actions
.
append
((
name
,
text
))
# TODO: Use namedtuple
self
.
_actions_data
[
name
]
=
(
attr
,
text
,
desc
)
def
is_action_allowed
(
self
,
name
):
return
True
def
get_actions_list
(
self
):
actions
=
[]
actions_confirmation
=
{}
for
act
in
self
.
_actions
:
name
,
text
=
act
if
self
.
is_action_allowed
(
name
):
text
=
unicode
(
text
)
actions
.
append
((
name
,
text
))
actions_confirmation
[
name
]
=
unicode
(
self
.
_actions_data
[
name
][
2
])
return
actions
,
actions_confirmation
def
handle_action
(
self
,
return_view
=
None
):
action
=
request
.
form
.
get
(
'action'
)
ids
=
request
.
form
.
getlist
(
'rowid'
)
handler
=
self
.
_actions_data
.
get
(
action
)
if
handler
and
self
.
is_action_allowed
(
action
):
response
=
handler
[
0
](
ids
)
if
response
is
not
None
:
return
response
if
not
return_view
:
url
=
url_for
(
'.'
+
self
.
_default_view
)
else
:
url
=
url_for
(
'.'
+
return_view
)
return
redirect
(
url
)
flask_admin/model/action.py
deleted
100644 → 0
View file @
73256448
def
action
(
name
,
text
,
confirmation
=
None
):
"""
Use this decorator to expose mass-model actions
`name`
Action name
`text`
Action text.
Will be passed through gettext() before rendering.
`confirmation`
Confirmation text. If not provided, action will be executed
unconditionally.
Will be passed through gettext() before rendering.
"""
def
wrap
(
f
):
f
.
_action
=
(
name
,
text
,
confirmation
)
return
f
return
wrap
flask_admin/model/base.py
View file @
373448cb
...
@@ -5,9 +5,10 @@ from flask.ext.admin.babel import gettext
...
@@ -5,9 +5,10 @@ from flask.ext.admin.babel import gettext
from
flask.ext.admin.base
import
BaseView
,
expose
from
flask.ext.admin.base
import
BaseView
,
expose
from
flask.ext.admin.tools
import
rec_getattr
from
flask.ext.admin.tools
import
rec_getattr
from
flask.ext.admin.model
import
filters
from
flask.ext.admin.model
import
filters
from
flask.ext.admin.actions
import
ActionsMixin
class
BaseModelView
(
BaseView
):
class
BaseModelView
(
BaseView
,
ActionsMixin
):
"""
"""
Base model view.
Base model view.
...
@@ -230,7 +231,7 @@ class BaseModelView(BaseView):
...
@@ -230,7 +231,7 @@ class BaseModelView(BaseView):
self
.
model
=
model
self
.
model
=
model
# Actions
# Actions
self
.
_
init_actions
()
self
.
init_actions
()
# Scaffolding
# Scaffolding
self
.
_refresh_cache
()
self
.
_refresh_cache
()
...
@@ -275,22 +276,6 @@ class BaseModelView(BaseView):
...
@@ -275,22 +276,6 @@ class BaseModelView(BaseView):
self
.
_filter_groups
=
None
self
.
_filter_groups
=
None
self
.
_filter_types
=
None
self
.
_filter_types
=
None
# Actions
def
_init_actions
(
self
):
self
.
_actions
=
[]
self
.
_action_data
=
dict
()
for
p
in
dir
(
self
):
attr
=
getattr
(
self
,
p
)
if
hasattr
(
attr
,
'_action'
):
name
,
text
,
desc
=
attr
.
_action
self
.
_actions
.
append
((
name
,
text
))
# TODO: Use namedtuple
self
.
_action_data
[
name
]
=
(
attr
,
text
,
desc
)
# Primary key
# Primary key
def
get_pk_value
(
self
,
model
):
def
get_pk_value
(
self
,
model
):
"""
"""
...
@@ -715,18 +700,8 @@ class BaseModelView(BaseView):
...
@@ -715,18 +700,8 @@ class BaseModelView(BaseView):
return
self
.
_get_url
(
'.index_view'
,
page
,
column
,
desc
,
return
self
.
_get_url
(
'.index_view'
,
page
,
column
,
desc
,
search
,
filters
)
search
,
filters
)
# Actions.
# Actions
actions
=
[]
actions
,
actions_confirmation
=
self
.
get_actions_list
()
actions_confirmation
=
{}
for
act
in
self
.
_actions
:
name
,
text
=
act
if
self
.
is_action_allowed
(
name
):
text
=
unicode
(
text
)
actions
.
append
((
name
,
text
))
actions_confirmation
[
name
]
=
unicode
(
self
.
_action_data
[
name
][
2
])
return
self
.
render
(
self
.
list_template
,
return
self
.
render
(
self
.
list_template
,
data
=
data
,
data
=
data
,
...
@@ -851,15 +826,4 @@ class BaseModelView(BaseView):
...
@@ -851,15 +826,4 @@ class BaseModelView(BaseView):
"""
"""
Mass-model action view.
Mass-model action view.
"""
"""
action
=
request
.
form
.
get
(
'action'
)
return
self
.
handle_action
()
ids
=
request
.
form
.
getlist
(
'rowid'
)
handler
=
self
.
_action_data
.
get
(
action
)
if
handler
and
self
.
is_action_allowed
(
action
):
response
=
handler
[
0
](
ids
)
if
response
is
not
None
:
return
response
return
redirect
(
url_for
(
'.index_view'
))
flask_admin/static/js/actions.js
0 → 100644
View file @
373448cb
var
AdminModelActions
=
function
(
actionErrorMessage
,
actionConfirmations
)
{
// Actions helpers. TODO: Move to separate file
this
.
execute
=
function
(
name
)
{
var
selected
=
$
(
'input.action-checkbox:checked'
).
size
();
if
(
selected
===
0
)
{
alert
(
actionErrorMessage
);
return
false
;
}
var
msg
=
actionConfirmations
[
name
];
if
(
!!
msg
)
if
(
!
confirm
(
msg
))
return
false
;
// Update hidden form and submit it
var
form
=
$
(
'#action_form'
);
$
(
'#action'
,
form
).
val
(
name
);
$
(
'input.action-checkbox'
,
form
).
remove
();
$
(
'input.action-checkbox:checked'
).
each
(
function
()
{
form
.
append
(
$
(
this
).
clone
());
});
form
.
submit
();
return
false
;
};
$
(
function
()
{
$
(
'#rowtoggle'
).
change
(
function
()
{
$
(
'td input[type=checkbox]'
).
attr
(
'checked'
,
this
.
checked
);
});
});
};
flask_admin/templates/admin/actions.html
0 → 100644
View file @
373448cb
{% macro dropdown(actions) -%}
{% if actions %}
<li
class=
"dropdown"
>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
{{ _gettext('With selected')}}
<b
class=
"caret"
></b>
</a>
<ul
id=
"action_list"
class=
"dropdown-menu"
>
{% for p in actions %}
<li>
<a
href=
"#"
onclick=
"return modelActions.execute('{{ p[0] }}');"
>
{{ _gettext(p[1]) }}
</a>
</li>
{% endfor %}
</ul>
</li>
{% endif %}
{% endmacro %}
{% macro form(actions, view) %}
{% if actions %}
<form
id=
"action_form"
action=
"{{ url_for(view) }}"
method=
"POST"
style=
"display: none"
>
<input
type=
"hidden"
id=
"action"
name=
"action"
/>
</form>
{% endif %}
{% endmacro %}
{% macro script(message, actions, actions_confirmation) %}
{% if actions %}
<script
src=
"{{ url_for('admin.static', filename='js/actions.js') }}"
></script>
<script
language=
"javascript"
>
var
modelActions
=
new
AdminModelActions
({{
message
|
tojson
|
safe
}},
{{
actions_confirmation
|
tojson
|
safe
}});
</script>
{% endif %}
{% endmacro %}
\ No newline at end of file
flask_admin/templates/admin/model/list.html
View file @
373448cb
{% extends 'admin/master.html' %}
{% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib with context %}
{% import 'admin/lib.html' as lib with context %}
{% import 'admin/actions.html' as actionlib with context %}
{% block head %}
{% block head %}
<link
href=
"{{ url_for('admin.static', filename='chosen/chosen.css') }}"
rel=
"stylesheet"
>
<link
href=
"{{ url_for('admin.static', filename='chosen/chosen.css') }}"
rel=
"stylesheet"
>
...
@@ -32,20 +33,7 @@
...
@@ -32,20 +33,7 @@
</li>
</li>
{% endif %}
{% endif %}
{% if actions %}
{{ actionlib.dropdown(actions) }}
<li
class=
"dropdown"
>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
{{ _gettext('With selected')}}
<b
class=
"caret"
></b>
</a>
<ul
id=
"action_list"
class=
"dropdown-menu"
>
{% for p in actions %}
<li>
<a
href=
"#"
onclick=
"return modelActions.execute('{{ p[0] }}');"
>
{{ _gettext(p[1]) }}
</a>
</li>
{% endfor %}
</ul>
</li>
{% endif %}
{% if search_supported %}
{% if search_supported %}
<li>
<li>
...
@@ -107,7 +95,7 @@
...
@@ -107,7 +95,7 @@
<tr>
<tr>
{% if actions %}
{% if actions %}
<th
class=
"span1"
>
<th
class=
"span1"
>
<input
type=
"checkbox"
name=
"rowtoggle"
id=
"
rowtoggle"
/>
<input
type=
"checkbox"
name=
"rowtoggle"
class=
"action-
rowtoggle"
/>
</th>
</th>
{% endif %}
{% endif %}
<th
class=
"span1"
>
</th>
<th
class=
"span1"
>
</th>
...
@@ -166,24 +154,18 @@
...
@@ -166,24 +154,18 @@
</table>
</table>
{{ lib.pager(page, num_pages, pager_url) }}
{{ lib.pager(page, num_pages, pager_url) }}
{% if actions %}
{{ actionlib.form(actions, '.action_view') }}
<form
id=
"action_form"
action=
"{{ url_for('.action_view') }}"
method=
"POST"
style=
"display: none"
>
<input
type=
"hidden"
id=
"action"
name=
"action"
/>
</form>
{% endif %}
{% endblock %}
{% endblock %}
{% block tail %}
{% block tail %}
<script
src=
"{{ url_for('admin.static', filename='js/bootstrap-datepicker.js') }}"
></script>
<script
src=
"{{ url_for('admin.static', filename='js/bootstrap-datepicker.js') }}"
></script>
<script
src=
"{{ url_for('admin.static', filename='js/form.js') }}"
></script>
<script
src=
"{{ url_for('admin.static', filename='js/form.js') }}"
></script>
<script
src=
"{{ url_for('admin.static', filename='js/filters.js') }}"
></script>
<script
src=
"{{ url_for('admin.static', filename='js/filters.js') }}"
></script>
{% if actions %}
<script
src=
"{{ url_for('admin.static', filename='js/actions.js') }}"
></script>
{{ actionlib.script(_gettext('Please select at least one model.'),
<script
language=
"javascript"
>
actions,
var
modelActions
=
new
AdminModelActions
(
'{{ _gettext("Please select at least one model.") }}'
,
actions_confirmation) }}
{{
actions_confirmation
|
tojson
|
safe
}});
</script>
{% endif %}
{% if filter_groups is not none and filter_data is not none %}
{% if filter_groups is not none and filter_data is not none %}
<script
language=
"javascript"
>
<script
language=
"javascript"
>
var
form
=
new
AdminForm
();
var
form
=
new
AdminForm
();
...
...
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