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
2b87cd44
Commit
2b87cd44
authored
Mar 27, 2016
by
Paul Brown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add JSONField to SQLA backend
parent
32921060
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
88 additions
and
33 deletions
+88
-33
fields.py
flask_admin/contrib/geoa/fields.py
+4
-30
form.py
flask_admin/contrib/sqla/form.py
+4
-0
fields.py
flask_admin/form/fields.py
+29
-2
typefmt.py
flask_admin/model/typefmt.py
+15
-0
test_postgres.py
flask_admin/tests/sqla/test_postgres.py
+36
-1
No files found.
flask_admin/contrib/geoa/fields.py
View file @
2b87cd44
import
json
import
warnings
import
geoalchemy2
from
flask
import
current_app
from
shapely.geometry
import
shape
from
sqlalchemy
import
func
from
wtforms.fields
import
TextAreaField
from
.widgets
import
LeafletWidget
class
JSONField
(
TextAreaField
):
def
_value
(
self
):
if
self
.
raw_data
:
return
self
.
raw_data
[
0
]
if
self
.
data
:
return
self
.
data
return
""
def
process_formdata
(
self
,
valuelist
):
if
valuelist
:
value
=
valuelist
[
0
]
if
not
value
:
self
.
data
=
None
return
try
:
self
.
data
=
self
.
from_json
(
value
)
except
ValueError
:
self
.
data
=
None
raise
ValueError
(
self
.
gettext
(
'Invalid JSON'
))
from
flask_admin.form
import
JSONField
def
to_json
(
self
,
obj
):
return
json
.
dumps
(
obj
)
def
from_json
(
self
,
data
):
return
json
.
loads
(
data
)
from
.widgets
import
LeafletWidget
class
GeoJSONField
(
JSONField
):
widget
=
LeafletWidget
()
def
__init__
(
self
,
label
=
None
,
validators
=
None
,
geometry_type
=
"GEOMETRY"
,
srid
=
'-1'
,
session
=
None
,
**
kwargs
):
def
__init__
(
self
,
label
=
None
,
validators
=
None
,
geometry_type
=
"GEOMETRY"
,
srid
=
'-1'
,
session
=
None
,
**
kwargs
):
super
(
GeoJSONField
,
self
)
.
__init__
(
label
,
validators
,
**
kwargs
)
self
.
web_srid
=
4326
self
.
srid
=
srid
...
...
flask_admin/contrib/sqla/form.py
View file @
2b87cd44
...
...
@@ -350,6 +350,10 @@ class AdminModelConverter(ModelConverterBase):
inner_form
=
field_args
.
pop
(
'form'
,
HstoreForm
)
return
InlineHstoreList
(
InlineFormField
(
inner_form
),
**
field_args
)
@
converts
(
'JSON'
)
def
convert_JSON
(
self
,
field_args
,
**
extra
):
return
form
.
JSONField
(
**
field_args
)
def
_resolve_prop
(
prop
):
"""
...
...
flask_admin/form/fields.py
View file @
2b87cd44
import
time
import
datetime
import
json
from
wtforms
import
fields
,
widgets
from
wtforms
import
fields
from
flask_admin.babel
import
gettext
from
flask_admin._compat
import
text_type
,
as_unicode
...
...
@@ -11,7 +12,8 @@ from . import widgets as admin_widgets
An understanding of WTForms's Custom Widgets is helpful for understanding this code: http://wtforms.simplecodes.com/docs/0.6.2/widgets.html#custom-widgets
"""
__all__
=
[
'DateTimeField'
,
'TimeField'
,
'Select2Field'
,
'Select2TagsField'
]
__all__
=
[
'DateTimeField'
,
'TimeField'
,
'Select2Field'
,
'Select2TagsField'
,
'JSONField'
]
class
DateTimeField
(
fields
.
DateTimeField
):
...
...
@@ -176,3 +178,28 @@ class Select2TagsField(fields.StringField):
return
as_unicode
(
self
.
data
)
else
:
return
u''
class
JSONField
(
fields
.
TextAreaField
):
def
_value
(
self
):
if
self
.
raw_data
:
return
self
.
raw_data
[
0
]
elif
self
.
data
:
# prevent utf8 characters from being converted to ascii
return
as_unicode
(
json
.
dumps
(
self
.
data
,
ensure_ascii
=
False
))
else
:
return
''
def
process_formdata
(
self
,
valuelist
):
if
valuelist
:
value
=
valuelist
[
0
]
# allow saving blank field as None
if
not
value
:
self
.
data
=
None
return
try
:
self
.
data
=
json
.
loads
(
valuelist
[
0
])
except
ValueError
:
raise
ValueError
(
self
.
gettext
(
'Invalid JSON'
))
flask_admin/model/typefmt.py
View file @
2b87cd44
import
json
from
jinja2
import
Markup
from
flask_admin._compat
import
text_type
try
:
...
...
@@ -58,15 +60,28 @@ def enum_formatter(view, value):
return
value
.
name
def
dict_formatter
(
view
,
value
):
"""
Removes unicode entities when displaying dict as string. Also unescapes
non-ASCII characters stored in the JSON.
:param value:
Dict to convert to string
"""
return
json
.
dumps
(
value
,
ensure_ascii
=
False
)
BASE_FORMATTERS
=
{
type
(
None
):
empty_formatter
,
bool
:
bool_formatter
,
list
:
list_formatter
,
dict
:
dict_formatter
,
}
EXPORT_FORMATTERS
=
{
type
(
None
):
empty_formatter
,
list
:
list_formatter
,
dict
:
dict_formatter
,
}
if
Enum
is
not
None
:
...
...
flask_admin/tests/sqla/test_postgres.py
View file @
2b87cd44
...
...
@@ -3,7 +3,7 @@ from nose.tools import eq_, ok_
from
.
import
setup_postgres
from
.test_basic
import
CustomModelView
from
sqlalchemy.dialects.postgresql
import
HSTORE
from
sqlalchemy.dialects.postgresql
import
HSTORE
,
JSON
def
test_hstore
():
...
...
@@ -40,3 +40,38 @@ def test_hstore():
data
=
rv
.
data
.
decode
(
'utf-8'
)
ok_
(
'test_val1'
in
data
)
ok_
(
'test_val2'
in
data
)
def
test_json
():
app
,
db
,
admin
=
setup_postgres
()
class
JSONModel
(
db
.
Model
):
id
=
db
.
Column
(
db
.
Integer
,
primary_key
=
True
,
autoincrement
=
True
)
json_test
=
db
.
Column
(
JSON
)
db
.
create_all
()
view
=
CustomModelView
(
JSONModel
,
db
.
session
)
admin
.
add_view
(
view
)
client
=
app
.
test_client
()
rv
=
client
.
get
(
'/admin/jsonmodel/'
)
eq_
(
rv
.
status_code
,
200
)
rv
=
client
.
post
(
'/admin/jsonmodel/new/'
,
data
=
{
'json_test'
:
'{"test_key1": "test_value1"}'
,
})
eq_
(
rv
.
status_code
,
302
)
rv
=
client
.
get
(
'/admin/jsonmodel/'
)
eq_
(
rv
.
status_code
,
200
)
data
=
rv
.
data
.
decode
(
'utf-8'
)
ok_
(
'json_test'
in
data
)
ok_
(
'{"test_key1": "test_value1"}'
in
data
)
rv
=
client
.
get
(
'/admin/jsonmodel/edit/?id=1'
)
eq_
(
rv
.
status_code
,
200
)
data
=
rv
.
data
.
decode
(
'utf-8'
)
ok_
(
'json_test'
in
data
)
ok_
(
'>{"test_key1": "test_value1"}<'
in
data
)
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