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
4383eef3
Commit
4383eef3
authored
Nov 01, 2012
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changed inline form conversion logic, fixed peewee support
parent
c1d85d3c
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
338 additions
and
100 deletions
+338
-100
.gitignore
.gitignore
+2
-0
filters.py
flask_admin/contrib/peeweemodel/filters.py
+5
-2
form.py
flask_admin/contrib/peeweemodel/form.py
+12
-31
tools.py
flask_admin/contrib/peeweemodel/tools.py
+11
-0
view.py
flask_admin/contrib/peeweemodel/view.py
+48
-16
form.py
flask_admin/contrib/sqlamodel/form.py
+40
-49
view.py
flask_admin/contrib/sqlamodel/view.py
+33
-2
form.py
flask_admin/model/form.py
+49
-0
__init__.py
flask_admin/tests/peeweemodel/__init__.py
+15
-0
test_basic.py
flask_admin/tests/peeweemodel/test_basic.py
+121
-0
test_basic.py
flask_admin/tests/sqlamodel/test_basic.py
+2
-0
No files found.
.gitignore
View file @
4383eef3
...
...
@@ -13,3 +13,5 @@ make.bat
venv
*.sqlite
*.sublime-*
.coverage
flask_admin/contrib/peeweemodel/filters.py
View file @
4383eef3
from
flask.ext.admin.babel
import
gettext
from
flask.ext.admin.model
import
filters
from
.tools
import
parse_like_term
class
BasePeeweeFilter
(
filters
.
BaseFilter
):
...
...
@@ -44,7 +45,8 @@ class FilterNotEqual(BasePeeweeFilter):
class
FilterLike
(
BasePeeweeFilter
):
def
apply
(
self
,
query
,
value
):
return
query
.
filter
(
self
.
column
**
value
)
term
=
parse_like_term
(
value
)
return
query
.
filter
(
self
.
column
**
term
)
def
operation
(
self
):
return
gettext
(
'contains'
)
...
...
@@ -52,7 +54,8 @@ class FilterLike(BasePeeweeFilter):
class
FilterNotLike
(
BasePeeweeFilter
):
def
apply
(
self
,
query
,
value
):
return
query
.
filter
(
~
(
self
.
column
**
value
))
term
=
parse_like_term
(
value
)
return
query
.
filter
(
~
(
self
.
column
**
term
))
def
operation
(
self
):
return
gettext
(
'not contains'
)
...
...
flask_admin/contrib/peeweemodel/form.py
View file @
4383eef3
...
...
@@ -5,7 +5,7 @@ from peewee import DateTimeField, DateField, TimeField, BaseModel, ForeignKeyFie
from
wtfpeewee.orm
import
ModelConverter
,
model_form
from
flask.ext.admin
import
form
from
flask.ext.admin.model.form
import
InlineFormAdmin
from
flask.ext.admin.model.form
import
InlineFormAdmin
,
InlineModelConverterBase
from
flask.ext.admin.model.fields
import
InlineModelFormField
from
flask.ext.admin.model.widgets
import
InlineFormListWidget
...
...
@@ -29,7 +29,8 @@ class InlineModelFormList(fields.FieldList):
def
process
(
self
,
formdata
,
data
=
None
):
if
not
formdata
:
data
=
self
.
model
.
select
()
.
where
(
user
=
data
)
.
execute
()
attr
=
getattr
(
self
.
model
,
self
.
prop
)
data
=
self
.
model
.
select
()
.
where
(
attr
==
data
)
.
execute
()
else
:
data
=
None
...
...
@@ -41,7 +42,8 @@ class InlineModelFormList(fields.FieldList):
def
save_related
(
self
,
obj
):
model_id
=
getattr
(
obj
,
self
.
_pk
)
values
=
self
.
model
.
select
()
.
where
(
user
=
model_id
)
.
execute
()
attr
=
getattr
(
self
.
model
,
self
.
prop
)
values
=
self
.
model
.
select
()
.
where
(
attr
==
model_id
)
.
execute
()
pk_map
=
dict
((
str
(
getattr
(
v
,
self
.
_pk
)),
v
)
for
v
in
values
)
...
...
@@ -85,37 +87,18 @@ class CustomModelConverter(ModelConverter):
return
field
.
name
,
form
.
TimeField
(
**
kwargs
)
def
contribute_inline
(
model
,
form_class
,
inline_models
):
# Contribute columns
for
p
in
inline_models
:
# Figure out settings
if
isinstance
(
p
,
tuple
):
info
=
InlineFormAdmin
(
p
[
0
],
**
p
[
1
])
elif
isinstance
(
p
,
InlineFormAdmin
):
info
=
p
elif
isinstance
(
p
,
BaseModel
):
info
=
InlineFormAdmin
(
p
)
else
:
model
=
getattr
(
p
,
'model'
,
None
)
if
model
is
None
:
raise
Exception
(
'Unknown inline model admin:
%
s'
%
repr
(
p
))
attrs
=
dict
()
for
attr
in
dir
(
p
):
if
not
attr
.
startswith
(
'_'
)
and
attr
!=
model
:
attrs
[
attr
]
=
getattr
(
p
,
attr
)
info
=
InlineFormAdmin
(
model
,
**
attrs
)
class
InlineModelConverter
(
InlineModelConverterBase
):
def
contribute
(
self
,
converter
,
model
,
form_class
,
inline_model
):
# Find property from target model to current model
reverse_field
=
None
info
=
self
.
get_info
(
inline_model
)
for
field
in
info
.
model
.
_meta
.
get_fields
():
field_type
=
type
(
field
)
if
field_type
==
ForeignKeyField
:
if
field
.
to
==
model
:
if
field
.
rel_model
==
model
:
reverse_field
=
field
break
else
:
...
...
@@ -130,7 +113,6 @@ def contribute_inline(model, form_class, inline_models):
exclude
=
ignore
# Create field
converter
=
CustomModelConverter
()
child_form
=
model_form
(
info
.
model
,
base_class
=
form
.
BaseForm
,
only
=
info
.
form_columns
,
...
...
@@ -140,7 +122,6 @@ def contribute_inline(model, form_class, inline_models):
converter
=
converter
)
prop_name
=
'fa_
%
s'
%
model
.
__name__
setattr
(
form_class
,
prop_name
,
InlineModelFormList
(
child_form
,
...
...
@@ -148,11 +129,11 @@ def contribute_inline(model, form_class, inline_models):
reverse_field
.
name
,
label
=
info
.
model
.
__name__
))
setattr
(
field
.
to
,
setattr
(
field
.
rel_model
,
prop_name
,
property
(
lambda
self
:
self
.
id
))
return
form_class
return
form_class
def
save_inline
(
form
,
model
):
...
...
flask_admin/contrib/peeweemodel/tools.py
View file @
4383eef3
...
...
@@ -5,3 +5,14 @@ def get_primary_key(model):
for
n
,
f
in
model
.
_meta
.
get_sorted_fields
():
if
type
(
f
)
==
PrimaryKeyField
:
return
n
def
parse_like_term
(
term
):
if
term
.
startswith
(
'^'
):
stmt
=
'
%
s
%%
'
%
term
[
1
:]
elif
term
.
startswith
(
'='
):
stmt
=
term
[
1
:]
else
:
stmt
=
'
%%%
s
%%
'
%
term
return
stmt
flask_admin/contrib/peeweemodel/view.py
View file @
4383eef3
import
logging
from
flask
import
flash
from
flask.ext.admin
import
form
...
...
@@ -9,8 +11,8 @@ from wtfpeewee.orm import model_form
from
flask.ext.admin.actions
import
action
from
flask.ext.admin.contrib.peeweemodel
import
filters
from
.form
import
CustomModelConverter
,
contribute_inline
,
save_inline
from
.tools
import
get_primary_key
from
.form
import
CustomModelConverter
,
InlineModelConverter
,
save_inline
from
.tools
import
get_primary_key
,
parse_like_term
class
ModelView
(
BaseModelView
):
...
...
@@ -45,6 +47,20 @@ class ModelView(BaseModelView):
model_form_converter = MyModelConverter
"""
inline_model_form_converter
=
InlineModelConverter
"""
Inline model conversion class. If you need some kind of post-processing for inline
forms, you can customize behavior by doing something like this::
class MyInlineModelConverter(AdminModelConverter):
def post_process(self, form_class, info):
form_class.value = wtf.TextField('value')
return form_class
class MyAdminView(ModelView):
inline_model_form_converter = MyInlineModelConverter
"""
filter_converter
=
filters
.
FilterConverter
()
"""
Field to filter converter.
...
...
@@ -165,8 +181,8 @@ class ModelView(BaseModelView):
raise
Exception
(
'Failed to find field for filter:
%
s'
%
name
)
# Check if field is in different model
if
attr
.
model
!=
self
.
model
:
visible_name
=
'
%
s /
%
s'
%
(
self
.
get_column_name
(
attr
.
model
.
__name__
),
if
attr
.
model
_class
!=
self
.
model
:
visible_name
=
'
%
s /
%
s'
%
(
self
.
get_column_name
(
attr
.
model
_class
.
__name__
),
self
.
get_column_name
(
attr
.
name
))
else
:
if
not
isinstance
(
name
,
basestring
):
...
...
@@ -193,16 +209,28 @@ class ModelView(BaseModelView):
converter
=
self
.
model_form_converter
())
if
self
.
inline_models
:
form_class
=
contribute_inline
(
self
.
model
,
form_class
,
self
.
inline_models
)
form_class
=
self
.
scaffold_inline_form_models
(
form_class
)
return
form_class
def
scaffold_inline_form_models
(
self
,
form_class
):
converter
=
self
.
model_form_converter
()
inline_converter
=
self
.
inline_model_form_converter
()
for
m
in
self
.
inline_models
:
form_class
=
inline_converter
.
contribute
(
converter
,
self
.
model
,
form_class
,
m
)
return
form_class
def
_handle_join
(
self
,
query
,
field
,
joins
):
if
field
.
model
!=
self
.
model
:
model_name
=
field
.
model
.
__name__
if
field
.
model
_class
!=
self
.
model
:
model_name
=
field
.
model
_class
.
__name__
if
model_name
not
in
joins
:
query
=
query
.
join
(
field
.
model
)
query
=
query
.
join
(
field
.
model
_class
)
joins
.
add
(
model_name
)
return
query
...
...
@@ -215,12 +243,14 @@ class ModelView(BaseModelView):
# Search
if
self
.
_search_supported
and
search
:
term
s
=
search
.
split
(
' '
)
value
s
=
search
.
split
(
' '
)
for
term
in
term
s
:
if
not
term
:
for
value
in
value
s
:
if
not
value
:
continue
term
=
parse_like_term
(
value
)
stmt
=
None
for
field
in
self
.
_search_fields
:
query
=
self
.
_handle_join
(
query
,
field
,
joins
)
...
...
@@ -250,14 +280,13 @@ class ModelView(BaseModelView):
sort_field
=
self
.
_sortable_columns
[
sort_column
]
if
isinstance
(
sort_field
,
basestring
):
query
=
query
.
order_by
((
sort_field
,
sort_desc
and
'desc'
or
'asc'
))
field
=
getattr
(
self
.
model
,
sort_field
)
query
=
query
.
order_by
(
field
.
desc
()
if
sort_desc
else
field
.
asc
())
elif
isinstance
(
sort_field
,
Field
):
if
sort_field
.
model
!=
self
.
model
:
if
sort_field
.
model
_class
!=
self
.
model
:
query
=
self
.
_handle_join
(
query
,
sort_field
,
joins
)
query
=
query
.
order_by
((
sort_field
.
model
,
sort_field
.
name
,
sort_desc
and
'desc'
or
'asc'
))
else
:
query
=
query
.
order_by
((
sort_column
,
sort_desc
and
'desc'
or
'asc'
))
query
=
query
.
order_by
(
sort_field
.
desc
()
if
sort_desc
else
sort_field
.
asc
())
# Pagination
if
page
is
not
None
:
...
...
@@ -286,6 +315,7 @@ class ModelView(BaseModelView):
return
True
except
Exception
,
ex
:
flash
(
gettext
(
'Failed to create model.
%(error)
s'
,
error
=
str
(
ex
)),
'error'
)
logging
.
exception
(
'Failed to create model'
)
return
False
def
update_model
(
self
,
form
,
model
):
...
...
@@ -300,6 +330,7 @@ class ModelView(BaseModelView):
return
True
except
Exception
,
ex
:
flash
(
gettext
(
'Failed to update model.
%(error)
s'
,
error
=
str
(
ex
)),
'error'
)
logging
.
exception
(
'Failed to update model'
)
return
False
def
delete_model
(
self
,
model
):
...
...
@@ -309,6 +340,7 @@ class ModelView(BaseModelView):
return
True
except
Exception
,
ex
:
flash
(
gettext
(
'Failed to delete model.
%(error)
s'
,
error
=
str
(
ex
)),
'error'
)
logging
.
exception
(
'Failed to delete model'
)
return
False
# Default model actions
...
...
flask_admin/contrib/sqlamodel/form.py
View file @
4383eef3
...
...
@@ -2,7 +2,7 @@ from wtforms import fields, validators
from
sqlalchemy
import
Boolean
,
Column
from
flask.ext.admin
import
form
from
flask.ext.admin.model.form
import
converts
,
ModelConverterBase
,
Inline
FormAdmin
from
flask.ext.admin.model.form
import
converts
,
ModelConverterBase
,
Inline
ModelConverterBase
from
.validators
import
Unique
from
.fields
import
QuerySelectField
,
QuerySelectMultipleField
,
InlineModelFormList
...
...
@@ -248,6 +248,7 @@ class AdminModelConverter(ModelConverterBase):
def
conv_ARRAY
(
self
,
field_args
,
**
extra
):
return
form
.
Select2TagsField
(
save_as_list
=
True
,
**
field_args
)
# Get list of fields and generate form
def
get_form
(
model
,
converter
,
base_class
=
form
.
BaseForm
,
...
...
@@ -319,53 +320,40 @@ def get_form(model, converter,
return
type
(
model
.
__name__
+
'Form'
,
(
base_class
,
),
field_dict
)
def
contribute_inline
(
session
,
model
,
form_class
,
inline_models
):
class
InlineModelConverter
(
InlineModelConverterBase
):
"""
Generate form fields for inline forms and contribute them to
the `form_class`
:param session:
SQLAlchemy session
:param model:
Model class
:param form_class:
Form to add properties to
:param inline_models:
List of inline model definitions. Can be one of:
- ``tuple``, first value is related model instance,
second is dictionary with options
- ``InlineFormAdmin`` instance
- Model class
:return:
Form class
Inline model form helper.
"""
def
__init__
(
self
,
session
):
self
.
session
=
session
# Get mapper
mapper
=
model
.
_sa_class_manager
.
mapper
# Contribute columns
for
p
in
inline_models
:
# Figure out settings
if
isinstance
(
p
,
tuple
):
info
=
InlineFormAdmin
(
p
[
0
],
**
p
[
1
])
elif
isinstance
(
p
,
InlineFormAdmin
):
info
=
p
elif
hasattr
(
p
,
'_sa_class_manager'
):
info
=
InlineFormAdmin
(
p
)
else
:
model
=
getattr
(
p
,
'model'
,
None
)
if
model
is
None
:
raise
Exception
(
'Unknown inline model admin:
%
s'
%
repr
(
p
))
attrs
=
dict
()
for
attr
in
dir
(
p
):
if
not
attr
.
startswith
(
'_'
)
and
attr
!=
'model'
:
attrs
[
attr
]
=
getattr
(
p
,
attr
)
info
=
InlineFormAdmin
(
model
,
**
attrs
)
def
contribute
(
self
,
converter
,
model
,
form_class
,
inline_model
):
"""
Generate form fields for inline forms and contribute them to
the `form_class`
:param converter:
ModelConverterBase instance
:param session:
SQLAlchemy session
:param model:
Model class
:param form_class:
Form to add properties to
:param inline_model:
Inline model. Can be one of:
- ``tuple``, first value is related model instance,
second is dictionary with options
- ``InlineFormAdmin`` instance
- Model class
:return:
Form class
"""
mapper
=
model
.
_sa_class_manager
.
mapper
info
=
self
.
get_info
(
inline_model
)
# Find property from target model to current model
target_mapper
=
info
.
model
.
_sa_class_manager
.
mapper
...
...
@@ -399,8 +387,7 @@ def contribute_inline(session, model, form_class, inline_models):
else
:
exclude
=
ignore
# Create field
converter
=
AdminModelConverter
(
session
,
info
)
# Create form
child_form
=
get_form
(
info
.
model
,
converter
,
only
=
info
.
form_columns
,
...
...
@@ -408,11 +395,15 @@ def contribute_inline(session, model, form_class, inline_models):
field_args
=
info
.
form_args
,
hidden_pk
=
True
)
# Post-process form
child_form
=
info
.
postprocess_form
(
child_form
)
# Contribute field
setattr
(
form_class
,
forward_prop
.
key
,
InlineModelFormList
(
child_form
,
session
,
se
lf
.
se
ssion
,
info
.
model
,
forward_prop
.
key
))
return
form_class
return
form_class
flask_admin/contrib/sqlamodel/view.py
View file @
4383eef3
...
...
@@ -124,6 +124,20 @@ class ModelView(BaseModelView):
model_form_converter = MyModelConverter
"""
inline_model_form_converter
=
form
.
InlineModelConverter
"""
Inline model conversion class. If you need some kind of post-processing for inline
forms, you can customize behavior by doing something like this::
class MyInlineModelConverter(AdminModelConverter):
def post_process(self, form_class, info):
form_class.value = wtf.TextField('value')
return form_class
class MyAdminView(ModelView):
inline_model_form_converter = MyInlineModelConverter
"""
filter_converter
=
filters
.
FilterConverter
()
"""
Field to filter converter.
...
...
@@ -425,8 +439,25 @@ class ModelView(BaseModelView):
field_args
=
self
.
form_args
)
if
self
.
inline_models
:
form_class
=
form
.
contribute_inline
(
self
.
session
,
self
.
model
,
form_class
,
self
.
inline_models
)
form_class
=
self
.
scaffold_inline_form_models
(
form_class
)
return
form_class
def
scaffold_inline_form_models
(
self
,
form_class
):
"""
Contribute inline models to the form
:param form_class:
Form class
"""
converter
=
self
.
model_form_converter
(
self
.
session
,
self
)
inline_converter
=
self
.
inline_model_form_converter
(
self
.
session
)
for
m
in
self
.
inline_models
:
form_class
=
inline_converter
.
contribute
(
converter
,
self
.
model
,
form_class
,
m
)
return
form_class
...
...
flask_admin/model/form.py
View file @
4383eef3
...
...
@@ -40,6 +40,22 @@ class InlineFormAdmin(object):
for
k
,
v
in
kwargs
.
iteritems
():
setattr
(
self
,
k
,
v
)
def
postprocess_form
(
self
,
form_class
):
"""
Post process form. Use this to contribute fields.
For example::
class MyInlineForm(InlineFormAdmin):
def postprocess_form(self, form):
form.value = wtf.TextField('value')
return form
class MyAdmin(ModelView):
inline_models = (MyInlineForm(ValueModel),)
"""
return
form_class
class
ModelConverterBase
(
object
):
def
__init__
(
self
,
converters
=
None
,
use_mro
=
True
):
...
...
@@ -80,3 +96,36 @@ class ModelConverterBase(object):
only
=
None
,
exclude
=
None
,
field_args
=
None
):
raise
NotImplemented
()
class
InlineModelConverterBase
(
object
):
def
get_info
(
self
,
p
):
"""
Figure out InlineFormAdmin information.
:param p:
Inline model. Can be one of:
- ``tuple``, first value is related model instance,
second is dictionary with options
- ``InlineFormAdmin`` instance
- Model class
"""
if
isinstance
(
p
,
tuple
):
return
InlineFormAdmin
(
p
[
0
],
**
p
[
1
])
elif
isinstance
(
p
,
InlineFormAdmin
):
return
p
elif
hasattr
(
p
,
'_sa_class_manager'
):
return
InlineFormAdmin
(
p
)
else
:
model
=
getattr
(
p
,
'model'
,
None
)
if
model
is
None
:
raise
Exception
(
'Unknown inline model admin:
%
s'
%
repr
(
p
))
attrs
=
dict
()
for
attr
in
dir
(
p
):
if
not
attr
.
startswith
(
'_'
)
and
attr
!=
'model'
:
attrs
[
attr
]
=
getattr
(
p
,
attr
)
return
InlineFormAdmin
(
model
,
**
attrs
)
flask_admin/tests/peeweemodel/__init__.py
0 → 100644
View file @
4383eef3
from
flask
import
Flask
from
flask.ext.admin
import
Admin
import
peewee
def
setup
():
app
=
Flask
(
__name__
)
app
.
config
[
'SECRET_KEY'
]
=
'1'
app
.
config
[
'CSRF_ENABLED'
]
=
False
app
.
config
[
'SQLALCHEMY_DATABASE_URI'
]
=
'sqlite:///'
db
=
peewee
.
SqliteDatabase
(
':memory:'
)
admin
=
Admin
(
app
)
return
app
,
db
,
admin
flask_admin/tests/peeweemodel/test_basic.py
0 → 100644
View file @
4383eef3
from
nose.tools
import
eq_
,
ok_
import
peewee
from
flask.ext
import
wtf
from
flask.ext.admin.contrib.peeweemodel
import
ModelView
from
.
import
setup
class
CustomModelView
(
ModelView
):
def
__init__
(
self
,
model
,
name
=
None
,
category
=
None
,
endpoint
=
None
,
url
=
None
,
**
kwargs
):
for
k
,
v
in
kwargs
.
iteritems
():
setattr
(
self
,
k
,
v
)
super
(
CustomModelView
,
self
)
.
__init__
(
model
,
name
,
category
,
endpoint
,
url
)
def
create_models
(
db
):
class
BaseModel
(
peewee
.
Model
):
class
Meta
:
database
=
db
class
Model1
(
BaseModel
):
def
__init__
(
self
,
test1
=
None
,
test2
=
None
,
test3
=
None
,
test4
=
None
):
super
(
Model1
,
self
)
.
__init__
()
self
.
test1
=
test1
self
.
test2
=
test2
self
.
test3
=
test3
self
.
test4
=
test4
test1
=
peewee
.
CharField
(
max_length
=
20
)
test2
=
peewee
.
CharField
(
max_length
=
20
)
test3
=
peewee
.
TextField
(
null
=
True
)
test4
=
peewee
.
TextField
(
null
=
True
)
class
Model2
(
BaseModel
):
int_field
=
peewee
.
IntegerField
()
bool_field
=
peewee
.
BooleanField
()
Model1
.
create_table
()
Model2
.
create_table
()
return
Model1
,
Model2
def
test_model
():
app
,
db
,
admin
=
setup
()
Model1
,
Model2
=
create_models
(
db
)
view
=
CustomModelView
(
Model1
)
admin
.
add_view
(
view
)
eq_
(
view
.
model
,
Model1
)
eq_
(
view
.
name
,
'Model1'
)
eq_
(
view
.
endpoint
,
'model1view'
)
eq_
(
view
.
_primary_key
,
'id'
)
ok_
(
'test1'
in
view
.
_sortable_columns
)
ok_
(
'test2'
in
view
.
_sortable_columns
)
ok_
(
'test3'
in
view
.
_sortable_columns
)
ok_
(
'test4'
in
view
.
_sortable_columns
)
ok_
(
view
.
_create_form_class
is
not
None
)
ok_
(
view
.
_edit_form_class
is
not
None
)
eq_
(
view
.
_search_supported
,
False
)
eq_
(
view
.
_filters
,
None
)
# Verify form
eq_
(
view
.
_create_form_class
.
test1
.
field_class
,
wtf
.
TextField
)
eq_
(
view
.
_create_form_class
.
test2
.
field_class
,
wtf
.
TextField
)
eq_
(
view
.
_create_form_class
.
test3
.
field_class
,
wtf
.
TextAreaField
)
eq_
(
view
.
_create_form_class
.
test4
.
field_class
,
wtf
.
TextAreaField
)
# Make some test clients
client
=
app
.
test_client
()
rv
=
client
.
get
(
'/admin/model1view/'
)
eq_
(
rv
.
status_code
,
200
)
rv
=
client
.
get
(
'/admin/model1view/new/'
)
eq_
(
rv
.
status_code
,
200
)
rv
=
client
.
post
(
'/admin/model1view/new/'
,
data
=
dict
(
test1
=
'test1large'
,
test2
=
'test2'
))
eq_
(
rv
.
status_code
,
302
)
model
=
Model1
.
select
()
.
get
()
eq_
(
model
.
test1
,
'test1large'
)
eq_
(
model
.
test2
,
'test2'
)
eq_
(
model
.
test3
,
None
)
eq_
(
model
.
test4
,
None
)
rv
=
client
.
get
(
'/admin/model1view/'
)
eq_
(
rv
.
status_code
,
200
)
ok_
(
'test1large'
in
rv
.
data
)
url
=
'/admin/model1view/edit/?id=
%
s'
%
model
.
id
rv
=
client
.
get
(
url
)
eq_
(
rv
.
status_code
,
200
)
rv
=
client
.
post
(
url
,
data
=
dict
(
test1
=
'test1small'
,
test2
=
'test2large'
))
eq_
(
rv
.
status_code
,
302
)
model
=
Model1
.
select
()
.
get
()
eq_
(
model
.
test1
,
'test1small'
)
eq_
(
model
.
test2
,
'test2large'
)
eq_
(
model
.
test3
,
None
)
eq_
(
model
.
test4
,
None
)
url
=
'/admin/model1view/delete/?id=
%
s'
%
model
.
id
rv
=
client
.
post
(
url
)
eq_
(
rv
.
status_code
,
302
)
eq_
(
Model1
.
select
()
.
count
(),
0
)
flask_admin/tests/sqlamodel/test_basic.py
View file @
4383eef3
...
...
@@ -5,6 +5,7 @@ from flask.ext.admin.contrib.sqlamodel import ModelView
from
.
import
setup
class
CustomModelView
(
ModelView
):
def
__init__
(
self
,
model
,
session
,
name
=
None
,
category
=
None
,
endpoint
=
None
,
url
=
None
,
...
...
@@ -16,6 +17,7 @@ class CustomModelView(ModelView):
name
,
category
,
endpoint
,
url
)
def
create_models
(
db
):
class
Model1
(
db
.
Model
):
def
__init__
(
self
,
test1
=
None
,
test2
=
None
,
test3
=
None
,
test4
=
None
):
...
...
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