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
a214377c
Commit
a214377c
authored
Jul 20, 2013
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added form_extra_columns. Fixed #256
parent
0b7107fb
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
321 additions
and
28 deletions
+321
-28
form.py
flask_admin/contrib/mongoengine/form.py
+81
-6
view.py
flask_admin/contrib/mongoengine/view.py
+11
-8
form.py
flask_admin/contrib/peewee/form.py
+26
-1
view.py
flask_admin/contrib/peewee/view.py
+7
-8
form.py
flask_admin/contrib/sqla/form.py
+18
-2
view.py
flask_admin/contrib/sqla/view.py
+2
-1
form.py
flask_admin/form.py
+14
-0
base.py
flask_admin/model/base.py
+25
-2
form.py
flask_admin/model/form.py
+8
-0
test_basic.py
flask_admin/tests/mongoengine/test_basic.py
+52
-0
test_basic.py
flask_admin/tests/peeweemodel/test_basic.py
+26
-0
test_basic.py
flask_admin/tests/sqlamodel/test_basic.py
+51
-0
No files found.
flask_admin/contrib/mongoengine/form.py
View file @
a214377c
from
operator
import
itemgetter
from
mongoengine
import
ReferenceField
from
mongoengine
import
ReferenceField
from
mongoengine.base
import
BaseDocument
,
DocumentMetaclass
from
wtforms
import
fields
,
validators
from
wtforms
import
fields
,
validators
from
flask.ext.mongoengine.wtf
import
orm
,
fields
as
mongo_fields
from
flask.ext.mongoengine.wtf
import
orm
,
fields
as
mongo_fields
from
flask.ext.admin
import
form
from
flask.ext.admin
import
form
from
flask.ext.admin.model.form
import
FieldPlaceholder
from
flask.ext.admin.model.fields
import
InlineFieldList
from
flask.ext.admin.model.fields
import
InlineFieldList
from
flask.ext.admin.model.widgets
import
InlineFormWidget
from
flask.ext.admin.model.widgets
import
InlineFormWidget
from
flask.ext.admin._compat
import
iteritems
from
.fields
import
ModelFormField
from
.fields
import
ModelFormField
...
@@ -32,6 +37,10 @@ class CustomModelConverter(orm.ModelConverter):
...
@@ -32,6 +37,10 @@ class CustomModelConverter(orm.ModelConverter):
return
None
return
None
def
convert
(
self
,
model
,
field
,
field_args
):
def
convert
(
self
,
model
,
field
,
field_args
):
# Check if it is overridden field
if
isinstance
(
field
,
FieldPlaceholder
):
return
form
.
recreate_field
(
field
.
field
)
kwargs
=
{
kwargs
=
{
'label'
:
getattr
(
field
,
'verbose_name'
,
field
.
name
),
'label'
:
getattr
(
field
,
'verbose_name'
,
field
.
name
),
'description'
:
field
.
help_text
or
''
,
'description'
:
field
.
help_text
or
''
,
...
@@ -86,6 +95,7 @@ class CustomModelConverter(orm.ModelConverter):
...
@@ -86,6 +95,7 @@ class CustomModelConverter(orm.ModelConverter):
doc_type
=
field
.
field
.
document_type
doc_type
=
field
.
field
.
document_type
return
mongo_fields
.
ModelSelectMultipleField
(
model
=
doc_type
,
**
kwargs
)
return
mongo_fields
.
ModelSelectMultipleField
(
model
=
doc_type
,
**
kwargs
)
if
field
.
field
.
choices
:
if
field
.
field
.
choices
:
kwargs
[
'multiple'
]
=
True
kwargs
[
'multiple'
]
=
True
return
self
.
convert
(
model
,
field
.
field
,
kwargs
)
return
self
.
convert
(
model
,
field
.
field
,
kwargs
)
...
@@ -105,7 +115,8 @@ class CustomModelConverter(orm.ModelConverter):
...
@@ -105,7 +115,8 @@ class CustomModelConverter(orm.ModelConverter):
'widget'
:
InlineFormWidget
()
'widget'
:
InlineFormWidget
()
}
}
form_class
=
model_form
(
field
.
document_type_obj
,
field_args
=
{})
# TODO: Configurable params?
form_class
=
get_form
(
field
.
document_type_obj
,
self
,
field_args
=
{})
return
ModelFormField
(
field
.
document_type_obj
,
form_class
,
**
kwargs
)
return
ModelFormField
(
field
.
document_type_obj
,
form_class
,
**
kwargs
)
@
orm
.
converts
(
'ReferenceField'
)
@
orm
.
converts
(
'ReferenceField'
)
...
@@ -114,8 +125,72 @@ class CustomModelConverter(orm.ModelConverter):
...
@@ -114,8 +125,72 @@ class CustomModelConverter(orm.ModelConverter):
return
orm
.
ModelConverter
.
conv_Reference
(
self
,
model
,
field
,
kwargs
)
return
orm
.
ModelConverter
.
conv_Reference
(
self
,
model
,
field
,
kwargs
)
def
model_form
(
model
,
base_class
=
form
.
BaseForm
,
only
=
None
,
exclude
=
None
,
def
get_form
(
model
,
converter
,
field_args
=
None
,
converter
=
None
):
base_class
=
form
.
BaseForm
,
return
orm
.
model_form
(
model
,
base_class
=
base_class
,
only
=
only
,
only
=
None
,
exclude
=
exclude
,
field_args
=
field_args
,
exclude
=
None
,
converter
=
converter
)
field_args
=
None
,
extra_fields
=
None
):
"""
Create a wtforms Form for a given mongoengine Document schema::
from flask.ext.mongoengine.wtf import model_form
from myproject.myapp.schemas import Article
ArticleForm = model_form(Article)
:param model:
A mongoengine Document schema class
:param base_class:
Base form class to extend from. Must be a ``wtforms.Form`` subclass.
:param only:
An optional iterable with the property names that should be included in
the form. Only these properties will have fields.
:param exclude:
An optional iterable with the property names that should be excluded
from the form. All other properties will have fields.
:param field_args:
An optional dictionary of field names mapping to keyword arguments used
to construct each field object.
:param converter:
A converter to generate the fields based on the model properties. If
not set, ``ModelConverter`` is used.
"""
if
not
isinstance
(
model
,
(
BaseDocument
,
DocumentMetaclass
)):
raise
TypeError
(
'Model must be a mongoengine Document schema'
)
field_args
=
field_args
or
{}
# Find properties
properties
=
((
k
,
v
)
for
k
,
v
in
iteritems
(
model
.
_fields
))
if
only
:
props
=
dict
(
properties
)
def
find
(
name
):
if
extra_fields
and
name
in
extra_fields
:
return
FieldPlaceholder
(
extra_fields
[
name
])
p
=
props
.
get
(
name
)
if
p
is
not
None
:
return
p
raise
ValueError
(
'Invalid model property name
%
s.
%
s'
%
(
model
,
name
))
properties
=
((
p
,
find
(
p
))
for
p
in
only
)
elif
exclude
:
properties
=
(
p
for
p
in
properties
in
p
[
0
]
not
in
exclude
)
# Create fields
field_dict
=
{}
for
name
,
p
in
properties
:
field
=
converter
.
convert
(
model
,
p
,
field_args
.
get
(
name
))
if
field
is
not
None
:
field_dict
[
name
]
=
field
# Contribute extra fields
if
not
only
and
extra_fields
:
for
name
,
field
in
iteritems
(
extra_fields
):
field_dict
[
name
]
=
form
.
recreate_field
(
field
)
field_dict
[
'model_class'
]
=
model
return
type
(
model
.
__name__
+
'Form'
,
(
base_class
,),
field_dict
)
flask_admin/contrib/mongoengine/view.py
View file @
a214377c
...
@@ -12,7 +12,7 @@ from bson.objectid import ObjectId
...
@@ -12,7 +12,7 @@ from bson.objectid import ObjectId
from
flask.ext.admin.actions
import
action
from
flask.ext.admin.actions
import
action
from
flask.ext.admin.form
import
BaseForm
from
flask.ext.admin.form
import
BaseForm
from
.filters
import
FilterConverter
,
BaseMongoEngineFilter
from
.filters
import
FilterConverter
,
BaseMongoEngineFilter
from
.form
import
model
_form
,
CustomModelConverter
from
.form
import
get
_form
,
CustomModelConverter
from
.typefmt
import
DEFAULT_FORMATTERS
from
.typefmt
import
DEFAULT_FORMATTERS
from
.tools
import
parse_like_term
from
.tools
import
parse_like_term
...
@@ -234,13 +234,16 @@ class ModelView(BaseModelView):
...
@@ -234,13 +234,16 @@ class ModelView(BaseModelView):
return
isinstance
(
filter
,
BaseMongoEngineFilter
)
return
isinstance
(
filter
,
BaseMongoEngineFilter
)
def
scaffold_form
(
self
):
def
scaffold_form
(
self
):
# TODO: Fix base_class
"""
form_class
=
model_form
(
self
.
model
,
Create form from the model.
base_class
=
BaseForm
,
"""
only
=
self
.
form_columns
,
form_class
=
get_form
(
self
.
model
,
exclude
=
self
.
form_excluded_columns
,
self
.
model_form_converter
(
self
),
field_args
=
self
.
form_args
,
base_class
=
BaseForm
,
converter
=
self
.
model_form_converter
(
self
))
only
=
self
.
form_columns
,
exclude
=
self
.
form_excluded_columns
,
field_args
=
self
.
form_args
,
extra_fields
=
self
.
form_extra_fields
)
return
form_class
return
form_class
...
...
flask_admin/contrib/peewee/form.py
View file @
a214377c
...
@@ -6,7 +6,7 @@ from peewee import (DateTimeField, DateField, TimeField,
...
@@ -6,7 +6,7 @@ from peewee import (DateTimeField, DateField, TimeField,
from
wtfpeewee.orm
import
ModelConverter
,
model_form
from
wtfpeewee.orm
import
ModelConverter
,
model_form
from
flask.ext.admin
import
form
from
flask.ext.admin
import
form
from
flask.ext.admin._compat
import
itervalues
from
flask.ext.admin._compat
import
iter
items
,
iter
values
from
flask.ext.admin.model.form
import
InlineFormAdmin
,
InlineModelConverterBase
from
flask.ext.admin.model.form
import
InlineFormAdmin
,
InlineModelConverterBase
from
flask.ext.admin.model.fields
import
InlineModelFormField
,
InlineFieldList
from
flask.ext.admin.model.fields
import
InlineModelFormField
,
InlineFieldList
...
@@ -103,6 +103,31 @@ class CustomModelConverter(ModelConverter):
...
@@ -103,6 +103,31 @@ class CustomModelConverter(ModelConverter):
return
field
.
name
,
form
.
TimeField
(
**
kwargs
)
return
field
.
name
,
form
.
TimeField
(
**
kwargs
)
def
get_form
(
model
,
converter
,
base_class
=
form
.
BaseForm
,
only
=
None
,
exclude
=
None
,
field_args
=
None
,
allow_pk
=
True
,
extra_fields
=
None
):
"""
Create form from peewee model and contribute extra fields, if necessary
"""
result
=
model_form
(
model
,
base_class
=
base_class
,
only
=
only
,
exclude
=
exclude
,
field_args
=
field_args
,
allow_pk
=
allow_pk
,
converter
=
converter
)
if
extra_fields
:
for
name
,
field
in
iteritems
(
extra_fields
):
setattr
(
result
,
name
,
form
.
recreate_field
(
field
))
return
result
class
InlineModelConverter
(
InlineModelConverterBase
):
class
InlineModelConverter
(
InlineModelConverterBase
):
"""
"""
Inline model form helper.
Inline model form helper.
...
...
flask_admin/contrib/peewee/view.py
View file @
a214377c
...
@@ -8,11 +8,10 @@ from flask.ext.admin.babel import gettext, ngettext, lazy_gettext
...
@@ -8,11 +8,10 @@ from flask.ext.admin.babel import gettext, ngettext, lazy_gettext
from
flask.ext.admin.model
import
BaseModelView
from
flask.ext.admin.model
import
BaseModelView
from
peewee
import
PrimaryKeyField
,
ForeignKeyField
,
Field
,
CharField
,
TextField
from
peewee
import
PrimaryKeyField
,
ForeignKeyField
,
Field
,
CharField
,
TextField
from
wtfpeewee.orm
import
model_form
from
flask.ext.admin.actions
import
action
from
flask.ext.admin.actions
import
action
from
flask.ext.admin.contrib.peewee
import
filters
from
flask.ext.admin.contrib.peewee
import
filters
from
.form
import
CustomModelConverter
,
InlineModelConverter
,
save_inline
from
.form
import
get_form
,
CustomModelConverter
,
InlineModelConverter
,
save_inline
from
.tools
import
get_primary_key
,
parse_like_term
from
.tools
import
get_primary_key
,
parse_like_term
...
@@ -218,12 +217,12 @@ class ModelView(BaseModelView):
...
@@ -218,12 +217,12 @@ class ModelView(BaseModelView):
return
isinstance
(
filter
,
filters
.
BasePeeweeFilter
)
return
isinstance
(
filter
,
filters
.
BasePeeweeFilter
)
def
scaffold_form
(
self
):
def
scaffold_form
(
self
):
form_class
=
model_form
(
self
.
model
,
form_class
=
get_form
(
self
.
model
,
self
.
model_form_converter
()
,
base_class
=
form
.
BaseForm
,
base_class
=
form
.
BaseForm
,
only
=
self
.
form_columns
,
only
=
self
.
form_columns
,
exclude
=
self
.
form_excluded_columns
,
exclude
=
self
.
form_excluded_columns
,
field_args
=
self
.
form_args
,
field_args
=
self
.
form_args
,
converter
=
self
.
model_form_converter
()
)
extra_fields
=
self
.
form_extra_fields
)
if
self
.
inline_models
:
if
self
.
inline_models
:
form_class
=
self
.
scaffold_inline_form_models
(
form_class
)
form_class
=
self
.
scaffold_inline_form_models
(
form_class
)
...
...
flask_admin/contrib/sqla/form.py
View file @
a214377c
...
@@ -4,8 +4,10 @@ from sqlalchemy import Boolean, Column
...
@@ -4,8 +4,10 @@ from sqlalchemy import Boolean, Column
from
flask.ext.admin
import
form
from
flask.ext.admin
import
form
from
flask.ext.admin.form
import
Select2Field
from
flask.ext.admin.form
import
Select2Field
from
flask.ext.admin.model.form
import
(
converts
,
ModelConverterBase
,
from
flask.ext.admin.model.form
import
(
converts
,
ModelConverterBase
,
InlineFormAdmin
,
InlineModelConverterBase
)
InlineFormAdmin
,
InlineModelConverterBase
,
FieldPlaceholder
)
from
flask.ext.admin._backwards
import
get_property
from
flask.ext.admin._backwards
import
get_property
from
flask.ext.admin._compat
import
iteritems
from
.validators
import
Unique
from
.validators
import
Unique
from
.fields
import
QuerySelectField
,
QuerySelectMultipleField
,
InlineModelFormList
from
.fields
import
QuerySelectField
,
QuerySelectMultipleField
,
InlineModelFormList
...
@@ -60,6 +62,10 @@ class AdminModelConverter(ModelConverterBase):
...
@@ -60,6 +62,10 @@ class AdminModelConverter(ModelConverterBase):
return
None
return
None
def
convert
(
self
,
model
,
mapper
,
prop
,
field_args
,
hidden_pk
):
def
convert
(
self
,
model
,
mapper
,
prop
,
field_args
,
hidden_pk
):
# Properly handle forced fields
if
isinstance
(
prop
,
FieldPlaceholder
):
return
form
.
recreate_field
(
prop
.
field
)
kwargs
=
{
kwargs
=
{
'validators'
:
[],
'validators'
:
[],
'filters'
:
[]
'filters'
:
[]
...
@@ -309,7 +315,8 @@ def get_form(model, converter,
...
@@ -309,7 +315,8 @@ def get_form(model, converter,
exclude
=
None
,
exclude
=
None
,
field_args
=
None
,
field_args
=
None
,
hidden_pk
=
False
,
hidden_pk
=
False
,
ignore_hidden
=
True
):
ignore_hidden
=
True
,
extra_fields
=
None
):
"""
"""
Generate form from the model.
Generate form from the model.
...
@@ -344,6 +351,10 @@ def get_form(model, converter,
...
@@ -344,6 +351,10 @@ def get_form(model, converter,
props
=
dict
(
properties
)
props
=
dict
(
properties
)
def
find
(
name
):
def
find
(
name
):
# If field is in extra_fields, it has higher priority
if
extra_fields
and
name
in
extra_fields
:
return
FieldPlaceholder
(
extra_fields
[
name
])
# Try to look it up in properties list first
# Try to look it up in properties list first
p
=
props
.
get
(
name
)
p
=
props
.
get
(
name
)
...
@@ -374,6 +385,11 @@ def get_form(model, converter,
...
@@ -374,6 +385,11 @@ def get_form(model, converter,
if
field
is
not
None
:
if
field
is
not
None
:
field_dict
[
name
]
=
field
field_dict
[
name
]
=
field
# Contribute extra fields
if
not
only
and
extra_fields
:
for
name
,
field
in
iteritems
(
extra_fields
):
field_dict
[
name
]
=
form
.
recreate_field
(
field
)
return
type
(
model
.
__name__
+
'Form'
,
(
base_class
,
),
field_dict
)
return
type
(
model
.
__name__
+
'Form'
,
(
base_class
,
),
field_dict
)
...
...
flask_admin/contrib/sqla/view.py
View file @
a214377c
...
@@ -515,7 +515,8 @@ class ModelView(BaseModelView):
...
@@ -515,7 +515,8 @@ class ModelView(BaseModelView):
form_class
=
form
.
get_form
(
self
.
model
,
converter
,
form_class
=
form
.
get_form
(
self
.
model
,
converter
,
only
=
self
.
form_columns
,
only
=
self
.
form_columns
,
exclude
=
self
.
form_excluded_columns
,
exclude
=
self
.
form_excluded_columns
,
field_args
=
self
.
form_args
)
field_args
=
self
.
form_args
,
extra_fields
=
self
.
form_extra_fields
)
if
self
.
inline_models
:
if
self
.
inline_models
:
form_class
=
self
.
scaffold_inline_form_models
(
form_class
)
form_class
=
self
.
scaffold_inline_form_models
(
form_class
)
...
...
flask_admin/form.py
View file @
a214377c
...
@@ -2,6 +2,7 @@ import time
...
@@ -2,6 +2,7 @@ import time
import
datetime
import
datetime
from
wtforms
import
form
,
fields
,
widgets
from
wtforms
import
form
,
fields
,
widgets
from
wtforms.fields.core
import
UnboundField
from
flask.globals
import
_request_ctx_stack
from
flask.globals
import
_request_ctx_stack
from
flask.ext.admin.babel
import
gettext
,
ngettext
from
flask.ext.admin.babel
import
gettext
,
ngettext
from
flask.ext.admin
import
helpers
as
h
from
flask.ext.admin
import
helpers
as
h
...
@@ -214,3 +215,16 @@ class Select2TagsField(fields.TextField):
...
@@ -214,3 +215,16 @@ class Select2TagsField(fields.TextField):
def
_value
(
self
):
def
_value
(
self
):
return
u', '
.
join
(
self
.
data
)
if
isinstance
(
self
.
data
,
list
)
else
self
.
data
return
u', '
.
join
(
self
.
data
)
if
isinstance
(
self
.
data
,
list
)
else
self
.
data
def
recreate_field
(
unbound
):
"""
Create new instance of the unbound field, resetting wtforms creation counter.
:param unbound:
UnboundField instance
"""
if
not
isinstance
(
unbound
,
UnboundField
):
raise
ValueError
(
'recreate_field expects UnboundField instance,
%
s was passed.'
%
type
(
unbound
))
return
unbound
.
field_class
(
*
unbound
.
args
,
**
unbound
.
kwargs
)
flask_admin/model/base.py
View file @
a214377c
...
@@ -12,7 +12,7 @@ from flask.ext.admin.actions import ActionsMixin
...
@@ -12,7 +12,7 @@ from flask.ext.admin.actions import ActionsMixin
from
flask.ext.admin.helpers
import
get_form_data
,
validate_form_on_submit
from
flask.ext.admin.helpers
import
get_form_data
,
validate_form_on_submit
from
flask.ext.admin.tools
import
rec_getattr
from
flask.ext.admin.tools
import
rec_getattr
from
flask.ext.admin._backwards
import
ObsoleteAttr
from
flask.ext.admin._backwards
import
ObsoleteAttr
from
flask.ext.admin._compat
import
as_unicode
from
flask.ext.admin._compat
import
iteritems
,
as_unicode
class
BaseModelView
(
BaseView
,
ActionsMixin
):
class
BaseModelView
(
BaseView
,
ActionsMixin
):
...
@@ -318,6 +318,29 @@ class BaseModelView(BaseView, ActionsMixin):
...
@@ -318,6 +318,29 @@ class BaseModelView(BaseView, ActionsMixin):
}
}
"""
"""
form_extra_fields
=
None
"""
Dictionary of additional fields.
Example::
class MyModelView(BaseModelView):
form_extra_fields = {
password: PasswordField('Password')
}
You can control order of form fields using ``form_columns`` property. For example::
class MyModelView(BaseModelView):
form_columns = ('name', 'email', 'password', 'secret')
form_extra_fields = {
password: PasswordField('Password')
}
In this case, password field will be put between email and secret fields that are autogenerated.
"""
# Actions
# Actions
action_disallowed_list
=
ObsoleteAttr
(
'action_disallowed_list'
,
action_disallowed_list
=
ObsoleteAttr
(
'action_disallowed_list'
,
'disallowed_actions'
,
'disallowed_actions'
,
...
@@ -876,7 +899,7 @@ class BaseModelView(BaseView, ActionsMixin):
...
@@ -876,7 +899,7 @@ class BaseModelView(BaseView, ActionsMixin):
"""
"""
Return flattened filter dictionary which can be JSON-serialized.
Return flattened filter dictionary which can be JSON-serialized.
"""
"""
return
dict
((
as_unicode
(
k
),
v
)
for
k
,
v
in
self
.
_filter_dict
.
iteritems
(
))
return
dict
((
as_unicode
(
k
),
v
)
for
k
,
v
in
iteritems
(
self
.
_filter_dict
))
@
contextfunction
@
contextfunction
def
get_list_value
(
self
,
context
,
model
,
name
):
def
get_list_value
(
self
,
context
,
model
,
name
):
...
...
flask_admin/model/form.py
View file @
a214377c
...
@@ -165,3 +165,11 @@ class InlineModelConverterBase(object):
...
@@ -165,3 +165,11 @@ class InlineModelConverterBase(object):
return
p
return
p
return
None
return
None
class
FieldPlaceholder
(
object
):
"""
Field placeholder for model convertors.
"""
def
__init__
(
self
,
field
):
self
.
field
=
field
flask_admin/tests/mongoengine/test_basic.py
View file @
a214377c
...
@@ -139,3 +139,55 @@ def test_default_sort():
...
@@ -139,3 +139,55 @@ def test_default_sort():
eq_
(
data
[
0
]
.
test1
,
'a'
)
eq_
(
data
[
0
]
.
test1
,
'a'
)
eq_
(
data
[
1
]
.
test1
,
'b'
)
eq_
(
data
[
1
]
.
test1
,
'b'
)
eq_
(
data
[
2
]
.
test1
,
'c'
)
eq_
(
data
[
2
]
.
test1
,
'c'
)
def
test_extra_fields
():
app
,
db
,
admin
=
setup
()
Model1
,
_
=
create_models
(
db
)
view
=
CustomModelView
(
Model1
,
form_extra_fields
=
{
'extra_field'
:
fields
.
TextField
(
'Extra Field'
)
}
)
admin
.
add_view
(
view
)
client
=
app
.
test_client
()
rv
=
client
.
get
(
'/admin/model1view/new/'
)
eq_
(
rv
.
status_code
,
200
)
# Check presence and order
data
=
rv
.
data
.
decode
(
'utf-8'
)
ok_
(
'Extra Field'
in
data
)
pos1
=
data
.
find
(
'Extra Field'
)
pos2
=
data
.
find
(
'Test1'
)
ok_
(
pos2
<
pos1
)
def
test_extra_field_order
():
app
,
db
,
admin
=
setup
()
Model1
,
_
=
create_models
(
db
)
view
=
CustomModelView
(
Model1
,
form_columns
=
(
'extra_field'
,
'test1'
),
form_extra_fields
=
{
'extra_field'
:
fields
.
TextField
(
'Extra Field'
)
}
)
admin
.
add_view
(
view
)
client
=
app
.
test_client
()
rv
=
client
.
get
(
'/admin/model1view/new/'
)
eq_
(
rv
.
status_code
,
200
)
# Check presence and order
data
=
rv
.
data
.
decode
(
'utf-8'
)
pos1
=
data
.
find
(
'Extra Field'
)
pos2
=
data
.
find
(
'Test1'
)
ok_
(
pos2
>
pos1
)
flask_admin/tests/peeweemodel/test_basic.py
View file @
a214377c
...
@@ -147,3 +147,29 @@ def test_default_sort():
...
@@ -147,3 +147,29 @@ def test_default_sort():
eq_
(
data
[
0
]
.
test1
,
'a'
)
eq_
(
data
[
0
]
.
test1
,
'a'
)
eq_
(
data
[
1
]
.
test1
,
'b'
)
eq_
(
data
[
1
]
.
test1
,
'b'
)
eq_
(
data
[
2
]
.
test1
,
'c'
)
eq_
(
data
[
2
]
.
test1
,
'c'
)
def
test_extra_fields
():
app
,
db
,
admin
=
setup
()
Model1
,
_
=
create_models
(
db
)
view
=
CustomModelView
(
Model1
,
form_extra_fields
=
{
'extra_field'
:
fields
.
TextField
(
'Extra Field'
)
}
)
admin
.
add_view
(
view
)
client
=
app
.
test_client
()
rv
=
client
.
get
(
'/admin/model1view/new/'
)
eq_
(
rv
.
status_code
,
200
)
# Check presence and order
data
=
rv
.
data
.
decode
(
'utf-8'
)
ok_
(
'Extra Field'
in
data
)
pos1
=
data
.
find
(
'Extra Field'
)
pos2
=
data
.
find
(
'Test1'
)
ok_
(
pos2
<
pos1
)
flask_admin/tests/sqlamodel/test_basic.py
View file @
a214377c
...
@@ -567,4 +567,55 @@ def test_default_sort():
...
@@ -567,4 +567,55 @@ def test_default_sort():
eq_
(
data
[
2
]
.
test1
,
'c'
)
eq_
(
data
[
2
]
.
test1
,
'c'
)
def
test_extra_fields
():
app
,
db
,
admin
=
setup
()
Model1
,
_
=
create_models
(
db
)
view
=
CustomModelView
(
Model1
,
db
.
session
,
form_extra_fields
=
{
'extra_field'
:
fields
.
TextField
(
'Extra Field'
)
}
)
admin
.
add_view
(
view
)
client
=
app
.
test_client
()
rv
=
client
.
get
(
'/admin/model1view/new/'
)
eq_
(
rv
.
status_code
,
200
)
# Check presence and order
data
=
rv
.
data
.
decode
(
'utf-8'
)
ok_
(
'Extra Field'
in
data
)
pos1
=
data
.
find
(
'Extra Field'
)
pos2
=
data
.
find
(
'Test1'
)
ok_
(
pos2
<
pos1
)
def
test_extra_field_order
():
app
,
db
,
admin
=
setup
()
Model1
,
_
=
create_models
(
db
)
view
=
CustomModelView
(
Model1
,
db
.
session
,
form_columns
=
(
'extra_field'
,
'test1'
),
form_extra_fields
=
{
'extra_field'
:
fields
.
TextField
(
'Extra Field'
)
}
)
admin
.
add_view
(
view
)
client
=
app
.
test_client
()
rv
=
client
.
get
(
'/admin/model1view/new/'
)
eq_
(
rv
.
status_code
,
200
)
# Check presence and order
data
=
rv
.
data
.
decode
(
'utf-8'
)
pos1
=
data
.
find
(
'Extra Field'
)
pos2
=
data
.
find
(
'Test1'
)
ok_
(
pos2
>
pos1
)
# TODO: Babel tests
# TODO: Babel tests
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