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
358ab3a5
Commit
358ab3a5
authored
Oct 26, 2018
by
PJ Janse van Rensburg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add support for more sqla utils fields.
parent
6f78ec70
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
94 additions
and
11 deletions
+94
-11
filters.py
flask_admin/contrib/sqla/filters.py
+2
-2
form.py
flask_admin/contrib/sqla/form.py
+34
-3
typefmt.py
flask_admin/contrib/sqla/typefmt.py
+27
-6
validators.py
flask_admin/contrib/sqla/validators.py
+31
-0
No files found.
flask_admin/contrib/sqla/filters.py
View file @
358ab3a5
...
...
@@ -384,7 +384,7 @@ class ChoiceTypeNotEqualFilter(FilterNotEqual):
break
if
choice_type
:
# != can exclude NULL values, so "or_ == None" needed to be added
return
query
.
filter
(
or_
(
column
!=
choice_type
,
column
==
None
))
return
query
.
filter
(
or_
(
column
!=
choice_type
,
column
==
None
))
# noqa: E711
else
:
return
query
...
...
@@ -431,7 +431,7 @@ class ChoiceTypeNotLikeFilter(FilterNotLike):
choice_types
.
append
(
type
)
if
choice_types
:
# != can exclude NULL values, so "or_ == None" needed to be added
return
query
.
filter
(
or_
(
column
.
notin_
(
choice_types
),
column
==
None
))
return
query
.
filter
(
or_
(
column
.
notin_
(
choice_types
),
column
==
None
))
# noqa: E711
else
:
return
query
...
...
flask_admin/contrib/sqla/form.py
View file @
358ab3a5
...
...
@@ -14,7 +14,7 @@ from flask_admin.model.helpers import prettify_name
from
flask_admin._backwards
import
get_property
from
flask_admin._compat
import
iteritems
,
text_type
from
.validators
import
Unique
from
.validators
import
Unique
,
valid_currency
,
valid_color
,
TimeZoneValidator
from
.fields
import
(
QuerySelectField
,
QuerySelectMultipleField
,
InlineModelFormList
,
InlineHstoreList
,
HstoreForm
)
from
flask_admin.model.fields
import
InlineFormField
...
...
@@ -341,11 +341,41 @@ class AdminModelConverter(ModelConverterBase):
def
convert_time
(
self
,
field_args
,
**
extra
):
return
form
.
TimeField
(
**
field_args
)
@
converts
(
'EmailType'
)
@
converts
(
'sqlalchemy_utils.types.arrow.ArrowType'
)
def
convert_arrow_time
(
self
,
field_args
,
**
extra
):
return
form
.
DateTimeField
(
**
field_args
)
@
converts
(
'sqlalchemy_utils.types.email.EmailType'
)
def
convert_email
(
self
,
field_args
,
**
extra
):
field_args
[
'validators'
]
.
append
(
validators
.
Email
())
return
fields
.
StringField
(
**
field_args
)
@
converts
(
'sqlalchemy_utils.types.url.URLType'
)
def
convert_url
(
self
,
field_args
,
**
extra
):
field_args
[
'validators'
]
.
append
(
validators
.
URL
())
return
fields
.
StringField
(
**
field_args
)
@
converts
(
'sqlalchemy_utils.types.ip_address.IPAddressType'
)
def
convert_ip_address
(
self
,
field_args
,
**
extra
):
field_args
[
'validators'
]
.
append
(
validators
.
IPAddress
())
return
fields
.
StringField
(
**
field_args
)
@
converts
(
'sqlalchemy_utils.types.color.ColorType'
)
def
convert_color
(
self
,
field_args
,
**
extra
):
field_args
[
'validators'
]
.
append
(
valid_color
)
return
fields
.
StringField
(
**
field_args
)
@
converts
(
'sqlalchemy_utils.types.currency.CurrencyType'
)
def
convert_currency
(
self
,
field_args
,
**
extra
):
field_args
[
'validators'
]
.
append
(
valid_currency
)
return
fields
.
StringField
(
**
field_args
)
@
converts
(
'sqlalchemy_utils.types.timezone.TimezoneType'
)
def
convert_timezone
(
self
,
column
,
field_args
,
**
extra
):
field_args
[
'validators'
]
.
append
(
TimeZoneValidator
(
coerce_function
=
column
.
type
.
_coerce
))
return
fields
.
StringField
(
**
field_args
)
@
converts
(
'Integer'
)
# includes BigInteger and SmallInteger
def
handle_integer_types
(
self
,
column
,
field_args
,
**
extra
):
unsigned
=
getattr
(
column
.
type
,
'unsigned'
,
False
)
...
...
@@ -371,7 +401,8 @@ class AdminModelConverter(ModelConverterBase):
field_args
[
'validators'
]
.
append
(
validators
.
MacAddress
())
return
fields
.
StringField
(
**
field_args
)
@
converts
(
'sqlalchemy.dialects.postgresql.base.UUID'
)
@
converts
(
'sqlalchemy.dialects.postgresql.base.UUID'
,
'sqlalchemy_utils.types.uuid.UUIDType'
)
def
conv_PGUuid
(
self
,
field_args
,
**
extra
):
field_args
.
setdefault
(
'label'
,
u'UUID'
)
field_args
[
'validators'
]
.
append
(
validators
.
UUID
())
...
...
flask_admin/contrib/sqla/typefmt.py
View file @
358ab3a5
...
...
@@ -3,12 +3,14 @@ from sqlalchemy.ext.associationproxy import _AssociationList
from
flask_admin.model.typefmt
import
BASE_FORMATTERS
,
EXPORT_FORMATTERS
,
\
DETAIL_FORMATTERS
,
list_formatter
from
sqlalchemy.orm.collections
import
InstrumentedList
from
sqlalchemy_utils.types
import
Choice
from
sqlalchemy_utils
import
Choice
from
arrow
import
Arrow
def
choice_formatter
(
view
,
choice
):
"""
Return label of selected choice
see https://sqlalchemy-utils.readthedocs.io/
:param choice:
sqlalchemy_utils Choice, which has a `code` and a `value`
...
...
@@ -16,6 +18,28 @@ def choice_formatter(view, choice):
return
choice
.
value
def
arrow_formatter
(
view
,
arrow_time
):
"""
Return human-friendly string of the time relative to now.
see https://arrow.readthedocs.io/
:param arrow_time:
Arrow object for handling datetimes
"""
return
arrow_time
.
humanize
()
def
arrow_export_formatter
(
view
,
arrow_time
):
"""
Return string representation of Arrow object
see https://arrow.readthedocs.io/
:param arrow_time:
Arrow object for handling datetimes
"""
return
arrow_time
.
format
()
DEFAULT_FORMATTERS
=
BASE_FORMATTERS
.
copy
()
EXPORT_FORMATTERS
=
EXPORT_FORMATTERS
.
copy
()
DETAIL_FORMATTERS
=
DETAIL_FORMATTERS
.
copy
()
...
...
@@ -24,12 +48,9 @@ DEFAULT_FORMATTERS.update({
InstrumentedList
:
list_formatter
,
_AssociationList
:
list_formatter
,
Choice
:
choice_formatter
,
Arrow
:
arrow_formatter
,
})
EXPORT_FORMATTERS
.
update
({
Choice
:
choice_formatter
,
})
DETAIL_FORMATTERS
.
update
({
Choice
:
choice_formatter
,
Arrow
:
arrow_export_formatter
,
})
flask_admin/contrib/sqla/validators.py
View file @
358ab3a5
from
sqlalchemy.orm.exc
import
NoResultFound
from
sqlalchemy_utils
import
Currency
from
colour
import
Color
from
wtforms
import
ValidationError
try
:
...
...
@@ -66,3 +68,32 @@ class ItemsRequired(InputRequired):
message
=
self
.
message
raise
ValidationError
(
message
)
def
valid_currency
(
form
,
field
):
try
:
Currency
(
field
.
data
)
except
(
TypeError
,
ValueError
):
raise
ValidationError
(
field
.
gettext
(
u'Not a valid ISO currency code (e.g. USD, EUR, CNY).'
))
def
valid_color
(
form
,
field
):
try
:
Color
(
field
.
data
)
except
(
ValueError
):
raise
ValidationError
(
field
.
gettext
(
u'Not a valid color (e.g. "red", "#f00", "#ff0000").'
))
class
TimeZoneValidator
(
object
):
"""
Tries to coerce a TimZone object from input data
"""
def
__init__
(
self
,
coerce_function
):
self
.
coerce_function
=
coerce_function
def
__call__
(
self
,
form
,
field
):
try
:
self
.
coerce_function
(
str
(
field
.
data
))
except
Exception
:
msg
=
u'Not a valid timezone (e.g. "America/New_York", "Africa/Johannesburg", "Asia/Singapore").'
raise
ValidationError
(
field
.
gettext
(
msg
))
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