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
29f17f21
Commit
29f17f21
authored
Oct 24, 2018
by
PJ Janse van Rensburg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Separate model-conversion methods for choice fields.
parent
5066d6d2
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
64 additions
and
24 deletions
+64
-24
form.py
flask_admin/contrib/sqla/form.py
+64
-24
No files found.
flask_admin/contrib/sqla/form.py
View file @
29f17f21
import
warnings
from
enum
import
Enum
,
EnumMeta
import
inspect
from
wtforms
import
fields
,
validators
from
sqlalchemy
import
Boolean
,
Column
...
...
@@ -244,9 +245,8 @@ class AdminModelConverter(ModelConverterBase):
if
override
:
return
override
(
**
kwargs
)
# Check choices
form_choices
=
getattr
(
self
.
view
,
'form_choices'
,
getattr
(
self
.
view
,
'choices'
,
None
))
# Check if a list of 'form_choices' are specified
form_choices
=
getattr
(
self
.
view
,
'form_choices'
,
None
)
if
mapper
.
class_
==
self
.
view
.
model
and
form_choices
:
choices
=
form_choices
.
get
(
prop
.
key
)
if
choices
:
...
...
@@ -264,7 +264,6 @@ class AdminModelConverter(ModelConverterBase):
return
converter
(
model
=
model
,
mapper
=
mapper
,
prop
=
prop
,
column
=
column
,
field_args
=
kwargs
)
return
None
@
classmethod
...
...
@@ -272,36 +271,54 @@ class AdminModelConverter(ModelConverterBase):
if
hasattr
(
column
.
type
,
'length'
)
and
isinstance
(
column
.
type
.
length
,
int
)
and
column
.
type
.
length
:
field_args
[
'validators'
]
.
append
(
validators
.
Length
(
max
=
column
.
type
.
length
))
@
converts
(
'String'
,
'ChoiceType'
)
# includes VARCHAR, CHAR, and Unicode
@
converts
(
'String'
)
# includes VARCHAR, CHAR, and Unicode
def
conv_String
(
self
,
column
,
field_args
,
**
extra
):
available_choices
=
[]
if
hasattr
(
column
.
type
,
'enums'
):
available_choices
=
[(
f
,
f
)
for
f
in
column
.
type
.
enums
]
elif
hasattr
(
column
.
type
,
'choices'
):
if
isinstance
(
column
.
type
.
choices
,
EnumMeta
):
available_choices
=
[(
str
(
f
.
value
),
f
.
name
)
for
f
in
column
.
type
.
choices
]
else
:
available_choices
=
column
.
type
.
choices
if
available_choices
:
field_args
[
'choices'
]
=
available_choices
accepted_values
=
[
key
for
key
,
val
in
available_choices
]
if
column
.
nullable
:
filters
=
field_args
.
get
(
'filters'
,
[])
filters
.
append
(
lambda
x
:
x
or
None
)
field_args
[
'filters'
]
=
filters
if
column
.
nullable
:
field_args
[
'allow_blank'
]
=
column
.
nullable
accepted_values
.
append
(
None
)
self
.
_string_common
(
column
=
column
,
field_args
=
field_args
,
**
extra
)
return
fields
.
StringField
(
**
field_args
)
@
converts
(
'sqlalchemy.sql.sqltypes.Enum'
)
def
convert_enum
(
self
,
column
,
field_args
,
**
extra
):
available_choices
=
[(
f
,
f
)
for
f
in
column
.
type
.
enums
]
accepted_values
=
[
key
for
key
,
val
in
available_choices
]
field_args
[
'validators'
]
.
append
(
validators
.
AnyOf
(
accepted_values
))
field_args
[
'coerce'
]
=
lambda
v
:
v
.
name
if
isinstance
(
v
,
Enum
)
else
(
v
.
code
if
isinstance
(
v
,
Choice
)
else
text_type
(
v
))
if
column
.
nullable
:
field_args
[
'allow_blank'
]
=
column
.
nullable
accepted_values
.
append
(
None
)
filters
=
field_args
.
get
(
'filters'
,
[])
filters
.
append
(
lambda
x
:
x
or
None
)
field_args
[
'filters'
]
=
filters
field_args
[
'choices'
]
=
available_choices
field_args
[
'validators'
]
.
append
(
validators
.
AnyOf
(
accepted_values
))
field_args
[
'coerce'
]
=
lambda
v
:
v
.
name
if
isinstance
(
v
,
Enum
)
else
text_type
(
v
)
return
form
.
Select2Field
(
**
field_args
)
return
form
.
Select2Field
(
**
field_args
)
@
converts
(
'sqlalchemy_utils.types.choice.ChoiceType'
)
def
convert_choice_type
(
self
,
column
,
field_args
,
**
extra
):
available_choices
=
[]
# choices can either be specified as an enum, or as a list of tuples
if
isinstance
(
column
.
type
.
choices
,
EnumMeta
):
available_choices
=
[(
f
.
value
,
f
.
name
)
for
f
in
column
.
type
.
choices
]
else
:
available_choices
=
column
.
type
.
choices
accepted_values
=
[
key
for
key
,
val
in
available_choices
]
if
column
.
nullable
:
field_args
[
'allow_blank'
]
=
column
.
nullable
accepted_values
.
append
(
None
)
filters
=
field_args
.
get
(
'filters'
,
[])
filters
.
append
(
lambda
x
:
x
or
None
)
field_args
[
'filters'
]
=
filters
self
.
_string_common
(
column
=
column
,
field_args
=
field_args
,
**
extra
)
return
fields
.
StringField
(
**
field_args
)
field_args
[
'choices'
]
=
available_choices
field_args
[
'validators'
]
.
append
(
validators
.
AnyOf
(
accepted_values
))
field_args
[
'coerce'
]
=
choice_type_coerce_factory
(
column
.
type
)
return
form
.
Select2Field
(
**
field_args
)
@
converts
(
'Text'
,
'LargeBinary'
,
'Binary'
,
'CIText'
)
# includes UnicodeText
def
conv_Text
(
self
,
field_args
,
**
extra
):
...
...
@@ -375,6 +392,29 @@ class AdminModelConverter(ModelConverterBase):
def
convert_JSON
(
self
,
field_args
,
**
extra
):
return
form
.
JSONField
(
**
field_args
)
def
choice_type_coerce_factory
(
type_
):
"""
Return a function needed to coerce a ChoiceTyped column. This function is
then passed to generated SelectField as the default coerce function.
:param type_: ChoiceType object
"""
choices
=
type_
.
choices
if
(
# Enum is not None and
isinstance
(
choices
,
type
)
and
issubclass
(
choices
,
Enum
)
):
key
,
choice_cls
=
'value'
,
choices
else
:
key
,
choice_cls
=
'code'
,
Choice
def
choice_coerce
(
value
):
if
value
is
None
:
return
None
if
isinstance
(
value
,
choice_cls
):
return
getattr
(
value
,
key
)
return
type_
.
python_type
(
value
)
return
choice_coerce
def
_resolve_prop
(
prop
):
"""
...
...
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