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
0d73f9a2
Commit
0d73f9a2
authored
Aug 26, 2013
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Unit tests
parent
890863fe
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
152 additions
and
1 deletion
+152
-1
ajax.py
flask_admin/contrib/sqla/ajax.py
+42
-0
ajax.py
flask_admin/model/ajax.py
+45
-0
base.py
flask_admin/model/base.py
+1
-1
__init__.py
flask_admin/tests/sqlamodel/__init__.py
+1
-0
test_basic.py
flask_admin/tests/sqlamodel/test_basic.py
+63
-0
No files found.
flask_admin/contrib/sqla/ajax.py
0 → 100644
View file @
0d73f9a2
from
sqlalchemy
import
or_
from
flask.ext.admin._compat
import
as_unicode
from
flask.ext.admin.model.ajax
import
AjaxModelLoader
,
DEFAULT_PAGE_SIZE
class
QueryAjaxModelLoader
(
AjaxModelLoader
):
def
__init__
(
self
,
name
,
session
,
model
,
fields
):
"""
Constructor.
:param fields:
Fields to run query against
"""
super
(
QueryAjaxModelLoader
,
self
)
.
__init__
(
name
)
self
.
session
=
session
self
.
model
=
model
self
.
fields
=
fields
primary_keys
=
model
.
_sa_class_manager
.
mapper
.
primary_key
if
len
(
primary_keys
)
>
1
:
raise
NotImplemented
(
'Flask-Admin does not support multi-pk AJAX model loading.'
)
self
.
pk
=
primary_keys
[
0
]
.
name
def
format
(
self
,
model
):
if
not
model
:
return
None
return
(
getattr
(
model
,
self
.
pk
),
as_unicode
(
model
))
def
get_one
(
self
,
pk
):
return
self
.
session
.
query
(
self
.
model
)
.
get
(
pk
)
def
get_list
(
self
,
term
,
offset
=
0
,
limit
=
DEFAULT_PAGE_SIZE
):
query
=
self
.
session
.
query
(
self
.
model
)
filters
=
(
field
.
like
(
'
%%%
s
%%
'
%
term
)
for
field
in
self
.
fields
)
query
=
query
.
filter
(
or_
(
*
filters
))
return
query
.
offset
(
offset
)
.
limit
(
limit
)
.
all
()
flask_admin/model/ajax.py
0 → 100644
View file @
0d73f9a2
DEFAULT_PAGE_SIZE
=
10
class
AjaxModelLoader
(
object
):
"""
Ajax related model loader. Override this to implement custom loading behavior.
"""
def
__init__
(
self
,
name
):
"""
Constructor.
:param name:
Field name
"""
self
.
name
=
name
def
format
(
self
,
model
):
"""
Return (id, name) tuple from the model.
"""
raise
NotImplemented
()
def
get_one
(
self
,
pk
):
"""
Find model by its primary key.
:param pk:
Primary key value
"""
raise
NotImplemented
()
def
get_list
(
self
,
query
,
offset
=
0
,
limit
=
DEFAULT_PAGE_SIZE
):
"""
Return models that match `query`.
:param view:
Administrative view.
:param query:
Query string
:param offset:
Offset
:param limit:
Limit
"""
raise
NotImplemented
()
flask_admin/model/base.py
View file @
0d73f9a2
...
@@ -1213,5 +1213,5 @@ class BaseModelView(BaseView, ActionsMixin):
...
@@ -1213,5 +1213,5 @@ class BaseModelView(BaseView, ActionsMixin):
if
not
loader
:
if
not
loader
:
abort
(
404
)
abort
(
404
)
data
=
[
loader
.
format
(
m
)
for
m
in
loader
.
get_
models
(
query
,
offset
,
limit
)]
data
=
[
loader
.
format
(
m
)
for
m
in
loader
.
get_
list
(
query
,
offset
,
limit
)]
return
Response
(
json
.
dumps
(
data
),
mimetype
=
'application/json'
)
return
Response
(
json
.
dumps
(
data
),
mimetype
=
'application/json'
)
flask_admin/tests/sqlamodel/__init__.py
View file @
0d73f9a2
...
@@ -8,6 +8,7 @@ def setup():
...
@@ -8,6 +8,7 @@ def setup():
app
.
config
[
'SECRET_KEY'
]
=
'1'
app
.
config
[
'SECRET_KEY'
]
=
'1'
app
.
config
[
'CSRF_ENABLED'
]
=
False
app
.
config
[
'CSRF_ENABLED'
]
=
False
app
.
config
[
'SQLALCHEMY_DATABASE_URI'
]
=
'sqlite:///'
app
.
config
[
'SQLALCHEMY_DATABASE_URI'
]
=
'sqlite:///'
#app.config['SQLALCHEMY_ECHO'] = True
db
=
SQLAlchemy
(
app
)
db
=
SQLAlchemy
(
app
)
admin
=
Admin
(
app
)
admin
=
Admin
(
app
)
...
...
flask_admin/tests/sqlamodel/test_basic.py
View file @
0d73f9a2
...
@@ -3,6 +3,7 @@ from nose.tools import eq_, ok_, raises
...
@@ -3,6 +3,7 @@ from nose.tools import eq_, ok_, raises
from
wtforms
import
fields
from
wtforms
import
fields
from
flask.ext.admin
import
form
from
flask.ext.admin
import
form
from
flask.ext.admin._compat
import
as_unicode
from
flask.ext.admin._compat
import
iteritems
from
flask.ext.admin._compat
import
iteritems
from
flask.ext.admin.contrib.sqla
import
ModelView
from
flask.ext.admin.contrib.sqla
import
ModelView
...
@@ -37,6 +38,9 @@ def create_models(db):
...
@@ -37,6 +38,9 @@ def create_models(db):
bool_field
=
db
.
Column
(
db
.
Boolean
)
bool_field
=
db
.
Column
(
db
.
Boolean
)
enum_field
=
db
.
Column
(
db
.
Enum
(
'model1_v1'
,
'model1_v1'
),
nullable
=
True
)
enum_field
=
db
.
Column
(
db
.
Enum
(
'model1_v1'
,
'model1_v1'
),
nullable
=
True
)
def
__str__
(
self
):
return
self
.
test1
class
Model2
(
db
.
Model
):
class
Model2
(
db
.
Model
):
def
__init__
(
self
,
string_field
=
None
,
int_field
=
None
,
bool_field
=
None
,
model1
=
None
):
def
__init__
(
self
,
string_field
=
None
,
int_field
=
None
,
bool_field
=
None
,
model1
=
None
):
self
.
string_field
=
string_field
self
.
string_field
=
string_field
...
@@ -675,3 +679,62 @@ def test_custom_form_base():
...
@@ -675,3 +679,62 @@ def test_custom_form_base():
create_form
=
view
.
create_form
()
create_form
=
view
.
create_form
()
ok_
(
isinstance
(
create_form
,
TestForm
))
ok_
(
isinstance
(
create_form
,
TestForm
))
def
test_ajax_fk
():
app
,
db
,
admin
=
setup
()
Model1
,
Model2
=
create_models
(
db
)
view
=
CustomModelView
(
Model2
,
db
.
session
,
url
=
'view'
,
form_ajax_refs
=
{
'model1'
:
(
'test1'
,
'test2'
)
}
)
admin
.
add_view
(
view
)
ok_
(
u'model1'
in
view
.
_form_ajax_refs
)
model
=
Model1
(
u'first'
)
db
.
session
.
add_all
([
model
,
Model1
(
u'foo'
,
u'bar'
)])
db
.
session
.
commit
()
# Check loader
loader
=
view
.
_form_ajax_refs
[
u'model1'
]
mdl
=
loader
.
get_one
(
model
.
id
)
eq_
(
mdl
.
test1
,
model
.
test1
)
items
=
loader
.
get_list
(
u'fir'
)
eq_
(
len
(
items
),
1
)
eq_
(
items
[
0
]
.
id
,
model
.
id
)
items
=
loader
.
get_list
(
u'bar'
)
eq_
(
len
(
items
),
1
)
eq_
(
items
[
0
]
.
test1
,
u'foo'
)
# Check form generation
form
=
view
.
create_form
()
eq_
(
form
.
model1
.
__class__
.
__name__
,
u'AjaxSelectField'
)
with
app
.
test_request_context
(
'/admin/view/'
):
ok_
(
u'value="null"'
in
form
.
model1
())
form
.
model1
.
data
=
model
ok_
(
u'value="[1, "first"]"'
in
form
.
model1
())
# Check querying
client
=
app
.
test_client
()
req
=
client
.
get
(
u'/admin/view/ajax/lookup/?name=model1&query=foo'
)
eq_
(
req
.
data
,
u'[[2, "foo"]]'
)
# Check submitting
req
=
client
.
post
(
'/admin/view/new/'
,
data
=
{
u'model1'
:
as_unicode
(
model
.
id
)})
mdl
=
db
.
session
.
query
(
Model2
)
.
first
()
ok_
(
mdl
is
not
None
)
ok_
(
mdl
.
model1
is
not
None
)
eq_
(
mdl
.
model1
.
id
,
model
.
id
)
eq_
(
mdl
.
model1
.
test1
,
u'first'
)
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