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
e9ef3bf6
Commit
e9ef3bf6
authored
Jul 01, 2019
by
P.J. Janse van Rensburg
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'minor-fixes'
parents
5c3ba0e2
c58bc0da
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
79 additions
and
9 deletions
+79
-9
changelog.rst
doc/changelog.rst
+1
-0
ajax.py
flask_admin/contrib/sqla/ajax.py
+5
-2
base.py
flask_admin/model/base.py
+20
-7
layout.html
flask_admin/templates/bootstrap2/admin/model/layout.html
+6
-0
layout.html
flask_admin/templates/bootstrap3/admin/model/layout.html
+6
-0
test_basic.py
flask_admin/tests/sqla/test_basic.py
+41
-0
No files found.
doc/changelog.rst
View file @
e9ef3bf6
...
@@ -7,6 +7,7 @@ Next release
...
@@ -7,6 +7,7 @@ Next release
* Fix display of inline x-editable boolean fields on list view
* Fix display of inline x-editable boolean fields on list view
* Add support for several SQLAlchemy-Utils data types
* Add support for several SQLAlchemy-Utils data types
* Support searching on SQLAlchemy hybrid properties
* Support searching on SQLAlchemy hybrid properties
* Extra URL paramaters are now propagated to the next page when searching / filtering
* Add enum34 dependency when running on legacy Python version
* Add enum34 dependency when running on legacy Python version
* Update Mapbox API v1 URL format
* Update Mapbox API v1 URL format
* Update jQuery and moment dependencies in templates
* Update jQuery and moment dependencies in templates
...
...
flask_admin/contrib/sqla/ajax.py
View file @
e9ef3bf6
...
@@ -58,13 +58,16 @@ class QueryAjaxModelLoader(AjaxModelLoader):
...
@@ -58,13 +58,16 @@ class QueryAjaxModelLoader(AjaxModelLoader):
return
getattr
(
model
,
self
.
pk
),
as_unicode
(
model
)
return
getattr
(
model
,
self
.
pk
),
as_unicode
(
model
)
def
get_query
(
self
):
return
self
.
session
.
query
(
self
.
model
)
def
get_one
(
self
,
pk
):
def
get_one
(
self
,
pk
):
# prevent autoflush from occuring during populate_obj
# prevent autoflush from occuring during populate_obj
with
self
.
session
.
no_autoflush
:
with
self
.
session
.
no_autoflush
:
return
self
.
session
.
query
(
self
.
model
)
.
get
(
pk
)
return
self
.
get_query
(
)
.
get
(
pk
)
def
get_list
(
self
,
term
,
offset
=
0
,
limit
=
DEFAULT_PAGE_SIZE
):
def
get_list
(
self
,
term
,
offset
=
0
,
limit
=
DEFAULT_PAGE_SIZE
):
query
=
self
.
session
.
query
(
self
.
model
)
query
=
self
.
get_query
(
)
filters
=
(
cast
(
field
,
String
)
.
ilike
(
u'
%%%
s
%%
'
%
term
)
for
field
in
self
.
_cached_fields
)
filters
=
(
cast
(
field
,
String
)
.
ilike
(
u'
%%%
s
%%
'
%
term
)
for
field
in
self
.
_cached_fields
)
query
=
query
.
filter
(
or_
(
*
filters
))
query
=
query
.
filter
(
or_
(
*
filters
))
...
...
flask_admin/model/base.py
View file @
e9ef3bf6
...
@@ -1701,29 +1701,39 @@ class BaseModelView(BaseView, ActionsMixin):
...
@@ -1701,29 +1701,39 @@ class BaseModelView(BaseView, ActionsMixin):
def
get_empty_list_message
(
self
):
def
get_empty_list_message
(
self
):
return
gettext
(
'There are no items in the table.'
)
return
gettext
(
'There are no items in the table.'
)
def
get_invalid_value_msg
(
self
,
value
,
filter
):
"""
Returns message, which should be printed in case of failed validation.
:param value: Invalid value
:param filter: Filter
:return: string
"""
return
gettext
(
'Invalid Filter Value:
%(value)
s'
,
value
=
value
)
# URL generation helpers
# URL generation helpers
def
_get_list_filter_args
(
self
):
def
_get_list_filter_args
(
self
):
if
self
.
_filters
:
if
self
.
_filters
:
filters
=
[]
filters
=
[]
for
n
in
request
.
args
:
for
arg
in
request
.
args
:
if
not
n
.
startswith
(
'flt'
):
if
not
arg
.
startswith
(
'flt'
):
continue
continue
if
'_'
not
in
n
:
if
'_'
not
in
arg
:
continue
continue
pos
,
key
=
n
[
3
:]
.
split
(
'_'
,
1
)
pos
,
key
=
arg
[
3
:]
.
split
(
'_'
,
1
)
if
key
in
self
.
_filter_args
:
if
key
in
self
.
_filter_args
:
idx
,
flt
=
self
.
_filter_args
[
key
]
idx
,
flt
=
self
.
_filter_args
[
key
]
value
=
request
.
args
[
n
]
value
=
request
.
args
[
arg
]
if
flt
.
validate
(
value
):
if
flt
.
validate
(
value
):
filters
.
append
((
pos
,
(
idx
,
as_unicode
(
flt
.
name
),
value
)))
data
=
(
pos
,
(
idx
,
as_unicode
(
flt
.
name
),
value
))
filters
.
append
(
data
)
else
:
else
:
flash
(
gettext
(
'Invalid Filter Value:
%(value)
s'
,
value
=
value
),
'error'
)
flash
(
self
.
get_invalid_value_msg
(
value
,
flt
),
'error'
)
# Sort filters
# Sort filters
return
[
v
[
1
]
for
v
in
sorted
(
filters
,
key
=
lambda
n
:
n
[
0
])]
return
[
v
[
1
]
for
v
in
sorted
(
filters
,
key
=
lambda
n
:
n
[
0
])]
...
@@ -2054,6 +2064,9 @@ class BaseModelView(BaseView, ActionsMixin):
...
@@ -2054,6 +2064,9 @@ class BaseModelView(BaseView, ActionsMixin):
get_pk_value
=
self
.
get_pk_value
,
get_pk_value
=
self
.
get_pk_value
,
get_value
=
self
.
get_list_value
,
get_value
=
self
.
get_list_value
,
return_url
=
self
.
_get_list_url
(
view_args
),
return_url
=
self
.
_get_list_url
(
view_args
),
# Extras
extra_args
=
view_args
.
extra_args
,
)
)
@
expose
(
'/new/'
,
methods
=
(
'GET'
,
'POST'
))
@
expose
(
'/new/'
,
methods
=
(
'GET'
,
'POST'
))
...
...
flask_admin/templates/bootstrap2/admin/model/layout.html
View file @
e9ef3bf6
...
@@ -34,6 +34,9 @@
...
@@ -34,6 +34,9 @@
{% macro filter_form() %}
{% macro filter_form() %}
<form
id=
"filter_form"
method=
"GET"
action=
"{{ return_url }}"
>
<form
id=
"filter_form"
method=
"GET"
action=
"{{ return_url }}"
>
{% for arg_name, arg_value in extra_args.items() %}
<input
type=
"hidden"
name=
"{{ arg_name }}"
value=
"{{ arg_value }}"
>
{% endfor %}
{% if sort_column is not none %}
{% if sort_column is not none %}
<input
type=
"hidden"
name=
"sort"
value=
"{{ sort_column }}"
>
<input
type=
"hidden"
name=
"sort"
value=
"{{ sort_column }}"
>
{% endif %}
{% endif %}
...
@@ -63,6 +66,9 @@
...
@@ -63,6 +66,9 @@
{% for flt_name, flt_value in filter_args.items() %}
{% for flt_name, flt_value in filter_args.items() %}
<input
type=
"hidden"
name=
"{{ flt_name }}"
value=
"{{ flt_value }}"
>
<input
type=
"hidden"
name=
"{{ flt_name }}"
value=
"{{ flt_value }}"
>
{% endfor %}
{% endfor %}
{% for arg_name, arg_value in extra_args.items() %}
<input
type=
"hidden"
name=
"{{ arg_name }}"
value=
"{{ arg_value }}"
>
{% endfor %}
{% if page_size != default_page_size %}
{% if page_size != default_page_size %}
<input
type=
"hidden"
name=
"page_size"
value=
"{{ page_size }}"
>
<input
type=
"hidden"
name=
"page_size"
value=
"{{ page_size }}"
>
{% endif %}
{% endif %}
...
...
flask_admin/templates/bootstrap3/admin/model/layout.html
View file @
e9ef3bf6
...
@@ -34,6 +34,9 @@
...
@@ -34,6 +34,9 @@
{% macro filter_form() %}
{% macro filter_form() %}
<form
id=
"filter_form"
method=
"GET"
action=
"{{ return_url }}"
>
<form
id=
"filter_form"
method=
"GET"
action=
"{{ return_url }}"
>
{% for arg_name, arg_value in extra_args.items() %}
<input
type=
"hidden"
name=
"{{ arg_name }}"
value=
"{{ arg_value }}"
>
{% endfor %}
{% if sort_column is not none %}
{% if sort_column is not none %}
<input
type=
"hidden"
name=
"sort"
value=
"{{ sort_column }}"
>
<input
type=
"hidden"
name=
"sort"
value=
"{{ sort_column }}"
>
{% endif %}
{% endif %}
...
@@ -63,6 +66,9 @@
...
@@ -63,6 +66,9 @@
{% for flt_name, flt_value in filter_args.items() %}
{% for flt_name, flt_value in filter_args.items() %}
<input
type=
"hidden"
name=
"{{ flt_name }}"
value=
"{{ flt_value }}"
>
<input
type=
"hidden"
name=
"{{ flt_name }}"
value=
"{{ flt_value }}"
>
{% endfor %}
{% endfor %}
{% for arg_name, arg_value in extra_args.items() %}
<input
type=
"hidden"
name=
"{{ arg_name }}"
value=
"{{ arg_value }}"
>
{% endfor %}
{% if page_size != default_page_size %}
{% if page_size != default_page_size %}
<input
type=
"hidden"
name=
"page_size"
value=
"{{ page_size }}"
>
<input
type=
"hidden"
name=
"page_size"
value=
"{{ page_size }}"
>
{% endif %}
{% endif %}
...
...
flask_admin/tests/sqla/test_basic.py
View file @
e9ef3bf6
...
@@ -436,6 +436,47 @@ def test_column_searchable_list():
...
@@ -436,6 +436,47 @@ def test_column_searchable_list():
ok_
(
'model2-test'
in
data
)
ok_
(
'model2-test'
in
data
)
def
test_extra_args_search
():
app
,
db
,
admin
=
setup
()
Model1
,
Model2
=
create_models
(
db
)
view1
=
CustomModelView
(
Model1
,
db
.
session
,
column_searchable_list
=
[
'test1'
,
])
admin
.
add_view
(
view1
)
db
.
session
.
add
(
Model2
(
'model1-test'
,
))
db
.
session
.
commit
()
client
=
app
.
test_client
()
# check that extra args in the url are propagated as hidden fields in the search form
rv
=
client
.
get
(
'/admin/model1/?search=model1&foo=bar'
)
data
=
rv
.
data
.
decode
(
'utf-8'
)
ok_
(
'<input type="hidden" name="foo" value="bar">'
in
data
)
def
test_extra_args_filter
():
app
,
db
,
admin
=
setup
()
Model1
,
Model2
=
create_models
(
db
)
view2
=
CustomModelView
(
Model2
,
db
.
session
,
column_filters
=
[
'int_field'
,
])
admin
.
add_view
(
view2
)
db
.
session
.
add
(
Model2
(
'model2-test'
,
5000
))
db
.
session
.
commit
()
client
=
app
.
test_client
()
# check that extra args in the url are propagated as hidden fields in the form
rv
=
client
.
get
(
'/admin/model2/?flt1_0=5000&foo=bar'
)
data
=
rv
.
data
.
decode
(
'utf-8'
)
ok_
(
'<input type="hidden" name="foo" value="bar">'
in
data
)
def
test_complex_searchable_list
():
def
test_complex_searchable_list
():
app
,
db
,
admin
=
setup
()
app
,
db
,
admin
=
setup
()
...
...
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