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
cbd5846a
Commit
cbd5846a
authored
Jul 21, 2013
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MongoEngine ImageField support. Fixes #257.
parent
125196d3
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
98 additions
and
44 deletions
+98
-44
simple.py
examples/mongoengine/simple.py
+6
-0
fields.py
flask_admin/contrib/mongoengine/fields.py
+4
-2
form.py
flask_admin/contrib/mongoengine/form.py
+5
-1
typefmt.py
flask_admin/contrib/mongoengine/typefmt.py
+28
-9
view.py
flask_admin/contrib/mongoengine/view.py
+12
-14
widgets.py
flask_admin/contrib/mongoengine/widgets.py
+33
-5
base.py
flask_admin/model/base.py
+1
-9
typefmt.py
flask_admin/model/typefmt.py
+4
-4
admin.css
flask_admin/static/admin/css/admin.css
+5
-0
No files found.
examples/mongoengine/simple.py
View file @
cbd5846a
...
@@ -64,6 +64,11 @@ class File(db.Document):
...
@@ -64,6 +64,11 @@ class File(db.Document):
data
=
db
.
FileField
()
data
=
db
.
FileField
()
class
Image
(
db
.
Document
):
name
=
db
.
StringField
(
max_length
=
20
)
image
=
db
.
ImageField
(
thumbnail_size
=
(
100
,
100
,
True
))
# Customized admin views
# Customized admin views
class
UserView
(
ModelView
):
class
UserView
(
ModelView
):
column_filters
=
[
'name'
]
column_filters
=
[
'name'
]
...
@@ -91,6 +96,7 @@ if __name__ == '__main__':
...
@@ -91,6 +96,7 @@ if __name__ == '__main__':
admin
.
add_view
(
ModelView
(
Tag
))
admin
.
add_view
(
ModelView
(
Tag
))
admin
.
add_view
(
ModelView
(
Post
))
admin
.
add_view
(
ModelView
(
Post
))
admin
.
add_view
(
ModelView
(
File
))
admin
.
add_view
(
ModelView
(
File
))
admin
.
add_view
(
ModelView
(
Image
))
# Start app
# Start app
app
.
run
(
debug
=
True
)
app
.
run
(
debug
=
True
)
flask_admin/contrib/mongoengine/fields.py
View file @
cbd5846a
...
@@ -30,8 +30,6 @@ class MongoFileField(fields.FileField):
...
@@ -30,8 +30,6 @@ class MongoFileField(fields.FileField):
if
field
is
not
None
:
if
field
is
not
None
:
data
=
request
.
files
.
get
(
self
.
name
)
data
=
request
.
files
.
get
(
self
.
name
)
print
data
.
filename
if
data
:
if
data
:
if
not
field
.
grid_id
:
if
not
field
.
grid_id
:
field
.
put
(
data
.
stream
,
field
.
put
(
data
.
stream
,
...
@@ -41,3 +39,7 @@ class MongoFileField(fields.FileField):
...
@@ -41,3 +39,7 @@ class MongoFileField(fields.FileField):
field
.
replace
(
data
.
stream
,
field
.
replace
(
data
.
stream
,
filename
=
data
.
filename
,
filename
=
data
.
filename
,
content_type
=
data
.
content_type
)
content_type
=
data
.
content_type
)
class
MongoImageField
(
MongoFileField
):
widget
=
widgets
.
MongoImageInput
()
flask_admin/contrib/mongoengine/form.py
View file @
cbd5846a
...
@@ -10,7 +10,7 @@ from flask.ext.admin.model.fields import InlineFieldList
...
@@ -10,7 +10,7 @@ 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
flask.ext.admin._compat
import
iteritems
from
.fields
import
ModelFormField
,
MongoFileField
from
.fields
import
ModelFormField
,
MongoFileField
,
MongoImageField
class
CustomModelConverter
(
orm
.
ModelConverter
):
class
CustomModelConverter
(
orm
.
ModelConverter
):
...
@@ -126,6 +126,10 @@ class CustomModelConverter(orm.ModelConverter):
...
@@ -126,6 +126,10 @@ class CustomModelConverter(orm.ModelConverter):
def
conv_File
(
self
,
model
,
field
,
kwargs
):
def
conv_File
(
self
,
model
,
field
,
kwargs
):
return
MongoFileField
(
**
kwargs
)
return
MongoFileField
(
**
kwargs
)
@
orm
.
converts
(
'ImageField'
)
def
conv_image
(
self
,
model
,
field
,
kwargs
):
return
MongoImageField
(
**
kwargs
)
def
get_form
(
model
,
converter
,
def
get_form
(
model
,
converter
,
base_class
=
form
.
BaseForm
,
base_class
=
form
.
BaseForm
,
...
...
flask_admin/contrib/mongoengine/typefmt.py
View file @
cbd5846a
...
@@ -2,23 +2,42 @@ from flask import url_for
...
@@ -2,23 +2,42 @@ from flask import url_for
from
jinja2
import
Markup
,
escape
from
jinja2
import
Markup
,
escape
from
mongoengine.base
import
BaseList
from
mongoengine.base
import
BaseList
from
mongoengine.fields
import
GridFSProxy
from
mongoengine.fields
import
GridFSProxy
,
ImageGridFsProxy
from
flask.ext.admin.model.typefmt
import
BASE_FORMATTERS
,
list_formatter
from
flask.ext.admin.model.typefmt
import
BASE_FORMATTERS
,
list_formatter
from
.
import
helpers
def
gridfs_formatter
(
view
,
model
,
name
,
value
):
def
grid_formatter
(
view
,
value
):
args
=
helpers
.
make_gridfs_args
(
value
)
return
Markup
(
(
'<a href="
%(url)
s" target="_blank">'
+
'<i class="icon-file"></i>
%(name)
s'
+
'</a>
%(size)
dk (
%(content_type)
s)'
)
%
{
'url'
:
url_for
(
'.api_file_view'
,
**
args
),
'name'
:
escape
(
value
.
filename
),
'size'
:
value
.
length
//
1024
,
'content_type'
:
escape
(
value
.
content_type
)
})
def
grid_image_formatter
(
view
,
value
):
return
Markup
(
return
Markup
(
'<a href="
%
s" target="_blank"><i class="icon-file"></i>
%
s</a>
%
dk (
%
s)'
%
(
(
'<div class="image-thumbnail">'
+
url_for
(
'.api_file_view'
,
id
=
model
.
id
,
name
=
name
),
'<a href="
%(url)
s" target="_blank"><img src="
%(thumb)
s"/></a>'
+
escape
(
value
.
filename
),
'</div>'
)
%
value
.
length
//
1024
,
{
escape
(
value
.
content_type
))
'url'
:
url_for
(
'.api_file_view'
,
**
helpers
.
make_gridfs_args
(
value
)),
)
'thumb'
:
url_for
(
'.api_file_view'
,
**
helpers
.
make_thumb_args
(
value
)),
})
DEFAULT_FORMATTERS
=
BASE_FORMATTERS
.
copy
()
DEFAULT_FORMATTERS
=
BASE_FORMATTERS
.
copy
()
DEFAULT_FORMATTERS
.
update
({
DEFAULT_FORMATTERS
.
update
({
BaseList
:
list_formatter
,
BaseList
:
list_formatter
,
GridFSProxy
:
gridfs_formatter
GridFSProxy
:
grid_formatter
,
ImageGridFsProxy
:
grid_image_formatter
})
})
flask_admin/contrib/mongoengine/view.py
View file @
cbd5846a
...
@@ -8,7 +8,9 @@ from flask.ext.admin.model import BaseModelView
...
@@ -8,7 +8,9 @@ from flask.ext.admin.model import BaseModelView
from
flask.ext.admin._compat
import
iteritems
,
string_types
from
flask.ext.admin._compat
import
iteritems
,
string_types
import
mongoengine
import
mongoengine
from
mongoengine.fields
import
GridFSProxy
import
gridfs
from
mongoengine.fields
import
GridFSProxy
,
ImageGridFsProxy
from
mongoengine.connection
import
get_db
from
bson.objectid
import
ObjectId
from
bson.objectid
import
ObjectId
from
flask.ext.admin.actions
import
action
from
flask.ext.admin.actions
import
action
...
@@ -408,26 +410,22 @@ class ModelView(BaseModelView):
...
@@ -408,26 +410,22 @@ class ModelView(BaseModelView):
@
expose
(
'/api/file/'
)
@
expose
(
'/api/file/'
)
def
api_file_view
(
self
):
def
api_file_view
(
self
):
pk
=
request
.
args
.
get
(
'id'
)
pk
=
request
.
args
.
get
(
'id'
)
name
=
request
.
args
.
get
(
'name'
)
coll
=
request
.
args
.
get
(
'coll'
)
db
=
request
.
args
.
get
(
'db'
,
'default'
)
if
not
pk
or
not
name
:
if
not
pk
or
not
coll
or
not
db
:
abort
(
404
)
abort
(
404
)
model
=
self
.
get_one
(
pk
)
fs
=
gridfs
.
GridFS
(
get_db
(
db
),
coll
)
if
model
is
None
:
abort
(
404
)
attr
=
getattr
(
model
,
name
,
None
)
if
attr
is
None
:
abort
(
404
)
if
type
(
attr
)
!=
GridFSProxy
:
data
=
fs
.
get
(
ObjectId
(
pk
))
if
not
data
:
abort
(
404
)
abort
(
404
)
return
Response
(
attr
.
read
(),
return
Response
(
data
.
read
(),
content_type
=
attr
.
content_type
,
content_type
=
data
.
content_type
,
headers
=
{
headers
=
{
'Content-Length'
:
attr
.
length
'Content-Length'
:
data
.
length
})
})
# Default model actions
# Default model actions
...
...
flask_admin/contrib/mongoengine/widgets.py
View file @
cbd5846a
from
wtforms.widgets
import
HTMLString
,
html_params
from
wtforms.widgets
import
HTMLString
,
html_params
from
jinja2
import
escape
from
jinja2
import
escape
from
flask
import
url_for
from
.
import
helpers
class
MongoFileInput
(
object
):
class
MongoFileInput
(
object
):
"""
"""
Renders a file input chooser field.
Renders a file input chooser field.
"""
"""
template
=
'<div><i class="icon-file"></i>
%(name)
s
%(length)
dk (
%(content_type)
s)</div>'
template
=
'<div><i class="icon-file"></i>
%(name)
s
%(size)
dk (
%(content_type)
s)</div>'
def
__call__
(
self
,
field
,
**
kwargs
):
kwargs
.
setdefault
(
'id'
,
field
.
id
)
placeholder
=
''
if
field
.
data
:
data
=
field
.
data
.
fs
placeholder
=
self
.
template
%
{
'name'
:
escape
(
data
.
filename
),
'content_type'
:
escape
(
data
.
content_type
),
'size'
:
data
.
length
//
1024
}
return
HTMLString
(
'
%
s<input
%
s>'
%
(
placeholder
,
html_params
(
name
=
field
.
name
,
type
=
'file'
,
**
kwargs
)))
class
MongoImageInput
(
object
):
"""
Renders a file input chooser field.
"""
template
=
'<div class="image-thumbnail"><img src="
%(thumb)
s"/></div>'
def
__call__
(
self
,
field
,
**
kwargs
):
def
__call__
(
self
,
field
,
**
kwargs
):
kwargs
.
setdefault
(
'id'
,
field
.
id
)
kwargs
.
setdefault
(
'id'
,
field
.
id
)
placeholder
=
''
placeholder
=
''
if
field
.
data
:
if
field
.
data
:
placeholder
=
self
.
template
%
dict
(
args
=
helpers
.
make_thumb_args
(
field
.
data
)
name
=
escape
(
field
.
data
.
filename
),
placeholder
=
self
.
template
%
{
content_type
=
escape
(
field
.
data
.
content_type
),
'thumb'
:
url_for
(
'.api_file_view'
,
**
args
)
length
=
field
.
data
.
length
//
1024
)
}
return
HTMLString
(
'
%
s<input
%
s>'
%
(
placeholder
,
return
HTMLString
(
'
%
s<input
%
s>'
%
(
placeholder
,
html_params
(
name
=
field
.
name
,
html_params
(
name
=
field
.
name
,
...
...
flask_admin/model/base.py
View file @
cbd5846a
...
@@ -940,15 +940,7 @@ class BaseModelView(BaseView, ActionsMixin):
...
@@ -940,15 +940,7 @@ class BaseModelView(BaseView, ActionsMixin):
type_fmt
=
self
.
column_type_formatters
.
get
(
type
(
value
))
type_fmt
=
self
.
column_type_formatters
.
get
(
type
(
value
))
if
type_fmt
is
not
None
:
if
type_fmt
is
not
None
:
try
:
value
=
type_fmt
(
self
,
value
)
value
=
type_fmt
(
self
,
model
,
name
,
value
)
except
TypeError
:
warnings
.
warn
(
'Type formatter prototype was changed to accept view, model, name and value as input parameters.
\n
'
+
'Please update
%
s
%
s formatter to accept 4 parameters.'
%
(
self
.
name
,
type
(
value
)),
stacklevel
=
2
)
self
.
column_type_formatters
[
type
(
value
)]
=
lambda
view
,
_model
,
_name
,
value
:
type_fmt
(
view
,
value
)
value
=
type_fmt
(
self
,
value
)
return
value
return
value
...
...
flask_admin/model/typefmt.py
View file @
cbd5846a
...
@@ -2,7 +2,7 @@ from jinja2 import Markup
...
@@ -2,7 +2,7 @@ from jinja2 import Markup
from
flask.ext.admin._compat
import
text_type
from
flask.ext.admin._compat
import
text_type
def
null_formatter
(
view
,
model
,
name
,
value
):
def
null_formatter
(
view
,
value
):
"""
"""
Return `NULL` as the string for `None` value
Return `NULL` as the string for `None` value
...
@@ -12,7 +12,7 @@ def null_formatter(view, model, name, value):
...
@@ -12,7 +12,7 @@ def null_formatter(view, model, name, value):
return
Markup
(
'<i>NULL</i>'
)
return
Markup
(
'<i>NULL</i>'
)
def
empty_formatter
(
view
,
model
,
name
,
value
):
def
empty_formatter
(
view
,
value
):
"""
"""
Return empty string for `None` value
Return empty string for `None` value
...
@@ -22,7 +22,7 @@ def empty_formatter(view, model, name, value):
...
@@ -22,7 +22,7 @@ def empty_formatter(view, model, name, value):
return
''
return
''
def
bool_formatter
(
view
,
model
,
name
,
value
):
def
bool_formatter
(
view
,
value
):
"""
"""
Return check icon if value is `True` or empty string otherwise.
Return check icon if value is `True` or empty string otherwise.
...
@@ -32,7 +32,7 @@ def bool_formatter(view, model, name, value):
...
@@ -32,7 +32,7 @@ def bool_formatter(view, model, name, value):
return
Markup
(
'<i class="icon-ok"></i>'
if
value
else
''
)
return
Markup
(
'<i class="icon-ok"></i>'
if
value
else
''
)
def
list_formatter
(
view
,
model
,
name
,
values
):
def
list_formatter
(
view
,
values
):
"""
"""
Return string with comma separated values
Return string with comma separated values
...
...
flask_admin/static/admin/css/admin.css
View file @
cbd5846a
...
@@ -77,6 +77,11 @@ table.filters {
...
@@ -77,6 +77,11 @@ table.filters {
float
:
right
;
float
:
right
;
}
}
/* Image thumbnails */
.image-thumbnail
img
{
max-width
:
100px
;
max-height
:
100px
;
}
/* Patch Select2 */
/* Patch Select2 */
.select2-results
li
{
.select2-results
li
{
...
...
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