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
0a239f91
Commit
0a239f91
authored
Mar 26, 2012
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Related models will use subqueryload in the sqla list view.
parent
528641b6
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
77 additions
and
13 deletions
+77
-13
TODO.txt
TODO.txt
+0
-3
mod_ext_sqlamodel.rst
doc/mod_ext_sqlamodel.rst
+7
-1
mod_form.rst
doc/mod_form.rst
+1
-1
sqlamodel.py
flask_adminex/ext/sqlamodel.py
+69
-8
No files found.
TODO.txt
View file @
0a239f91
...
...
@@ -13,10 +13,7 @@
- Custom paginator class?
- Custom CSS/JS in admin interface
- SQLA Model Admin
- Automatic required validator if field is not nullable
- Validation of the joins in the query
- Automatic joined load for foreign keys
- Through the hint
- Built-in filtering support
- Many2Many support
- Verify if it is working properly
...
...
doc/mod_ext_sqlamodel.rst
View file @
0a239f91
...
...
@@ -28,9 +28,14 @@
.. autoattribute:: BaseModelView.form_columns
.. autoattribute:: BaseModelView.form_args
.. autoattribute:: BaseModelView.page_size
SQLAlchemy-related Customizations
---------------------------------
.. autoattribute:: ModelView.hide_backrefs
.. autoattribute:: BaseModelView.page_size
.. autoattribute:: ModelView.auto_select_related
.. autoattribute:: ModelView.list_select_related
Constructor
-----------
...
...
@@ -83,3 +88,4 @@
------------
.. automethod:: ModelView._get_url
.. automethod:: ModelView.scaffold_auto_joins
\ No newline at end of file
doc/mod_form.rst
View file @
0a239f91
...
...
@@ -3,6 +3,6 @@
.. automodule:: flask.ext.adminex.form
.. autoclass::
Admin
Form
.. autoclass::
Base
Form
.. autoattribute:: has_file_field
flask_adminex/ext/sqlamodel.py
View file @
0a239f91
from
sqlalchemy.orm.attributes
import
InstrumentedAttribute
from
sqlalchemy.orm.exc
import
NoResultFound
from
sqlalchemy.orm
import
subqueryload
from
sqlalchemy.sql.expression
import
desc
from
wtforms
import
ValidationError
,
fields
,
validators
...
...
@@ -8,7 +9,8 @@ from wtforms.ext.sqlalchemy.fields import QuerySelectField, QuerySelectMultipleF
from
flask
import
flash
from
flask.ext.adminex
import
model
,
form
from
flask.ext.adminex
import
form
from
flask.ext.adminex.model
import
BaseModelView
class
Unique
(
object
):
...
...
@@ -141,7 +143,7 @@ class AdminModelConverter(ModelConverter):
return
form
.
TimeField
(
**
field_args
)
class
ModelView
(
model
.
BaseModelView
):
class
ModelView
(
BaseModelView
):
"""
SQLALchemy model view
...
...
@@ -156,6 +158,35 @@ class ModelView(model.BaseModelView):
Set this to False if you want to see multiselect for model backrefs.
"""
auto_select_related
=
True
"""
Enable automatic detection of displayed foreign keys in this view
and perform automatic joined loading for related models to improve
query performance.
Please note that detection is not recursive: if `__unicode__` method
of related model uses another model to generate string representation, it
will still make separate database call.
"""
list_select_related
=
None
"""
List of parameters for SQLAlchemy `subqueryload`. Overrides `auto_select_related`
property.
For example::
class PostAdmin(ModelAdmin):
list_select_related = ('user', 'city')
You can also use properties::
class PostAdmin(ModelAdmin):
list_select_related = (Post.user, Post.city)
Please refer to the `subqueryload` on list of possible values.
"""
def
__init__
(
self
,
model
,
session
,
name
=
None
,
category
=
None
,
endpoint
=
None
,
url
=
None
):
"""
...
...
@@ -178,6 +209,16 @@ class ModelView(model.BaseModelView):
super
(
ModelView
,
self
)
.
__init__
(
model
,
name
,
category
,
endpoint
,
url
)
# Configuration
if
not
self
.
list_select_related
:
self
.
_auto_joins
=
self
.
scaffold_auto_joins
()
else
:
self
.
_auto_joins
=
self
.
list_select_related
# Internal API
def
_get_model_iterator
(
self
):
return
self
.
model
.
_sa_class_manager
.
mapper
.
iterate_properties
# Scaffolding
def
scaffold_list_columns
(
self
):
"""
...
...
@@ -185,9 +226,7 @@ class ModelView(model.BaseModelView):
"""
columns
=
[]
mapper
=
self
.
model
.
_sa_class_manager
.
mapper
for
p
in
mapper
.
iterate_properties
:
for
p
in
self
.
_get_model_iterator
():
if
hasattr
(
p
,
'direction'
):
if
p
.
direction
.
name
==
'MANYTOONE'
:
columns
.
append
(
p
.
key
)
...
...
@@ -209,9 +248,7 @@ class ModelView(model.BaseModelView):
"""
columns
=
dict
()
mapper
=
self
.
model
.
_sa_class_manager
.
mapper
for
p
in
mapper
.
iterate_properties
:
for
p
in
self
.
_get_model_iterator
():
if
hasattr
(
p
,
'columns'
):
# Sanity check
if
len
(
p
.
columns
)
>
1
:
...
...
@@ -239,6 +276,26 @@ class ModelView(model.BaseModelView):
field_args
=
self
.
form_args
,
converter
=
AdminModelConverter
(
self
))
def
scaffold_auto_joins
(
self
):
"""
Return list of joined tables by going through the
displayed columns.
"""
relations
=
set
()
for
p
in
self
.
_get_model_iterator
():
if
hasattr
(
p
,
'direction'
):
if
p
.
direction
.
name
==
'MANYTOONE'
:
relations
.
add
(
p
.
key
)
joined
=
[]
for
prop
,
name
in
self
.
_list_columns
:
if
prop
in
relations
:
joined
.
append
(
getattr
(
self
.
model
,
prop
))
return
joined
# Database-related API
def
get_list
(
self
,
page
,
sort_column
,
sort_desc
,
execute
=
True
):
"""
...
...
@@ -257,6 +314,10 @@ class ModelView(model.BaseModelView):
count
=
query
.
count
()
# Auto join
for
j
in
self
.
_auto_joins
:
query
=
query
.
options
(
subqueryload
(
j
))
# Sorting
if
sort_column
is
not
None
:
if
sort_column
in
self
.
_sortable_columns
:
...
...
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