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
fa757fc6
Commit
fa757fc6
authored
Jul 21, 2013
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MongoEngine GridFS support
parent
9dc0af0f
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
120 additions
and
28 deletions
+120
-28
.gitignore
.gitignore
+1
-0
simple.py
examples/mongoengine/simple.py
+6
-0
fields.py
flask_admin/contrib/mongoengine/fields.py
+26
-2
form.py
flask_admin/contrib/mongoengine/form.py
+5
-3
typefmt.py
flask_admin/contrib/mongoengine/typefmt.py
+17
-1
view.py
flask_admin/contrib/mongoengine/view.py
+30
-2
widgets.py
flask_admin/contrib/mongoengine/widgets.py
+25
-0
base.py
flask_admin/model/base.py
+6
-16
typefmt.py
flask_admin/model/typefmt.py
+4
-4
No files found.
.gitignore
View file @
fa757fc6
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
*.swo
*.swo
*.pyc
*.pyc
*.*~
*.*~
*.rdb
*.egg-info
*.egg-info
pyenv
pyenv
#*#
#*#
...
...
examples/mongoengine/simple.py
View file @
fa757fc6
...
@@ -59,6 +59,11 @@ class Post(db.Document):
...
@@ -59,6 +59,11 @@ class Post(db.Document):
lols
=
db
.
ListField
(
db
.
StringField
(
max_length
=
20
))
lols
=
db
.
ListField
(
db
.
StringField
(
max_length
=
20
))
class
File
(
db
.
Document
):
name
=
db
.
StringField
(
max_length
=
20
)
data
=
db
.
FileField
()
# Customized admin views
# Customized admin views
class
UserView
(
ModelView
):
class
UserView
(
ModelView
):
column_filters
=
[
'name'
]
column_filters
=
[
'name'
]
...
@@ -85,6 +90,7 @@ if __name__ == '__main__':
...
@@ -85,6 +90,7 @@ if __name__ == '__main__':
admin
.
add_view
(
TodoView
(
Todo
))
admin
.
add_view
(
TodoView
(
Todo
))
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
))
# Start app
# Start app
app
.
run
(
debug
=
True
)
app
.
run
(
debug
=
True
)
flask_admin/contrib/mongoengine/fields.py
View file @
fa757fc6
from
wtforms.fields
import
FormField
from
flask
import
request
from
wtforms
import
fields
from
.
import
widgets
class
ModelFormField
(
FormField
):
class
ModelFormField
(
fields
.
FormField
):
"""
"""
Customized ModelFormField for MongoEngine EmbeddedDocuments.
Customized ModelFormField for MongoEngine EmbeddedDocuments.
"""
"""
...
@@ -17,3 +20,24 @@ class ModelFormField(FormField):
...
@@ -17,3 +20,24 @@ class ModelFormField(FormField):
setattr
(
obj
,
name
,
candidate
)
setattr
(
obj
,
name
,
candidate
)
self
.
form
.
populate_obj
(
candidate
)
self
.
form
.
populate_obj
(
candidate
)
class
MongoFileField
(
fields
.
FileField
):
widget
=
widgets
.
MongoFileInput
()
def
populate_obj
(
self
,
obj
,
name
):
field
=
getattr
(
obj
,
name
,
None
)
if
field
is
not
None
:
data
=
request
.
files
.
get
(
self
.
name
)
print
data
.
filename
if
data
:
if
not
field
.
grid_id
:
field
.
put
(
data
.
stream
,
filename
=
data
.
filename
,
content_type
=
data
.
content_type
)
else
:
field
.
replace
(
data
.
stream
,
filename
=
data
.
filename
,
content_type
=
data
.
content_type
)
flask_admin/contrib/mongoengine/form.py
View file @
fa757fc6
from
operator
import
itemgetter
from
mongoengine
import
ReferenceField
from
mongoengine
import
ReferenceField
from
mongoengine.base
import
BaseDocument
,
DocumentMetaclass
from
mongoengine.base
import
BaseDocument
,
DocumentMetaclass
...
@@ -12,7 +10,7 @@ from flask.ext.admin.model.fields import InlineFieldList
...
@@ -12,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
from
.fields
import
ModelFormField
,
MongoFileField
class
CustomModelConverter
(
orm
.
ModelConverter
):
class
CustomModelConverter
(
orm
.
ModelConverter
):
...
@@ -124,6 +122,10 @@ class CustomModelConverter(orm.ModelConverter):
...
@@ -124,6 +122,10 @@ class CustomModelConverter(orm.ModelConverter):
kwargs
[
'widget'
]
=
form
.
Select2Widget
()
kwargs
[
'widget'
]
=
form
.
Select2Widget
()
return
orm
.
ModelConverter
.
conv_Reference
(
self
,
model
,
field
,
kwargs
)
return
orm
.
ModelConverter
.
conv_Reference
(
self
,
model
,
field
,
kwargs
)
@
orm
.
converts
(
'FileField'
)
def
conv_File
(
self
,
model
,
field
,
kwargs
):
return
MongoFileField
(
**
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 @
fa757fc6
from
flask
import
url_for
from
jinja2
import
Markup
,
escape
from
mongoengine.base
import
BaseList
from
mongoengine.base
import
BaseList
from
mongoengine.fields
import
GridFSProxy
from
flask.ext.admin.model.typefmt
import
BASE_FORMATTERS
,
list_formatter
from
flask.ext.admin.model.typefmt
import
BASE_FORMATTERS
,
list_formatter
def
gridfs_formatter
(
view
,
model
,
name
,
value
):
return
Markup
(
'<a href="
%
s" target="_blank"><i class="icon-file"></i>
%
s</a>
%
dk (
%
s)'
%
(
url_for
(
'.api_file_view'
,
id
=
model
.
id
,
name
=
name
),
escape
(
value
.
filename
),
value
.
length
//
1024
,
escape
(
value
.
content_type
))
)
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
})
})
flask_admin/contrib/mongoengine/view.py
View file @
fa757fc6
import
logging
import
logging
from
flask
import
flash
from
flask
import
request
,
flash
,
abort
,
Response
from
flask.ext.admin
import
expose
from
flask.ext.admin.babel
import
gettext
,
ngettext
,
lazy_gettext
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
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
from
bson.objectid
import
ObjectId
from
bson.objectid
import
ObjectId
from
flask.ext.admin.actions
import
action
from
flask.ext.admin.actions
import
action
...
@@ -30,7 +32,7 @@ SORTABLE_FIELDS = set((
...
@@ -30,7 +32,7 @@ SORTABLE_FIELDS = set((
mongoengine
.
EmailField
,
mongoengine
.
EmailField
,
mongoengine
.
UUIDField
,
mongoengine
.
UUIDField
,
mongoengine
.
URLField
mongoengine
.
URLField
))
))
class
ModelView
(
BaseModelView
):
class
ModelView
(
BaseModelView
):
...
@@ -402,6 +404,32 @@ class ModelView(BaseModelView):
...
@@ -402,6 +404,32 @@ class ModelView(BaseModelView):
logging
.
exception
(
'Failed to delete model'
)
logging
.
exception
(
'Failed to delete model'
)
return
False
return
False
# FileField access API
@
expose
(
'/api/file/'
)
def
api_file_view
(
self
):
pk
=
request
.
args
.
get
(
'id'
)
name
=
request
.
args
.
get
(
'name'
)
if
not
pk
or
not
name
:
abort
(
404
)
model
=
self
.
get_one
(
pk
)
if
model
is
None
:
abort
(
404
)
attr
=
getattr
(
model
,
name
,
None
)
if
attr
is
None
:
abort
(
404
)
if
type
(
attr
)
!=
GridFSProxy
:
abort
(
404
)
return
Response
(
attr
.
read
(),
content_type
=
attr
.
content_type
,
headers
=
{
'Content-Length'
:
attr
.
length
})
# Default model actions
# Default model actions
def
is_action_allowed
(
self
,
name
):
def
is_action_allowed
(
self
,
name
):
# Check delete action permission
# Check delete action permission
...
...
flask_admin/contrib/mongoengine/widgets.py
0 → 100644
View file @
fa757fc6
from
wtforms.widgets
import
HTMLString
,
html_params
from
jinja2
import
escape
class
MongoFileInput
(
object
):
"""
Renders a file input chooser field.
"""
template
=
'<div><i class="icon-file"></i>
%(name)
s
%(length)
dk (
%(content_type)
s)</div>'
def
__call__
(
self
,
field
,
**
kwargs
):
kwargs
.
setdefault
(
'id'
,
field
.
id
)
placeholder
=
''
if
field
.
data
:
placeholder
=
self
.
template
%
dict
(
name
=
escape
(
field
.
data
.
filename
),
content_type
=
escape
(
field
.
data
.
content_type
),
length
=
field
.
data
.
length
//
1024
)
return
HTMLString
(
'
%
s<input
%
s>'
%
(
placeholder
,
html_params
(
name
=
field
.
name
,
type
=
'file'
,
**
kwargs
)))
flask_admin/model/base.py
View file @
fa757fc6
...
@@ -930,17 +930,7 @@ class BaseModelView(BaseView, ActionsMixin):
...
@@ -930,17 +930,7 @@ class BaseModelView(BaseView, ActionsMixin):
"""
"""
column_fmt
=
self
.
column_formatters
.
get
(
name
)
column_fmt
=
self
.
column_formatters
.
get
(
name
)
if
column_fmt
is
not
None
:
if
column_fmt
is
not
None
:
try
:
return
column_fmt
(
self
,
context
,
model
,
name
)
return
column_fmt
(
self
,
context
,
model
,
name
)
except
TypeError
:
warnings
.
warn
(
u'Column formatter prototype was changed to accept view as first input parameter.
\n
'
u'Please update
%
s
%
s formatter to accept 4 parameters.'
%
(
self
.
name
,
name
),
stacklevel
=
2
)
self
.
column_formatters
[
name
]
=
lambda
_
,
c
,
m
,
n
:
column_fmt
(
c
,
m
,
n
)
return
column_fmt
(
context
,
model
,
name
)
value
=
self
.
_get_field_value
(
model
,
name
)
value
=
self
.
_get_field_value
(
model
,
name
)
...
@@ -951,14 +941,14 @@ class BaseModelView(BaseView, ActionsMixin):
...
@@ -951,14 +941,14 @@ 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
:
try
:
value
=
type_fmt
(
self
,
value
)
value
=
type_fmt
(
self
,
model
,
name
,
value
)
except
TypeError
:
except
TypeError
:
warnings
.
warn
(
'Type formatter prototype was changed to accept view
as first input parameter
.
\n
'
+
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
2
parameters.'
%
(
self
.
name
,
type
(
value
)),
'Please update
%
s
%
s formatter to accept
4
parameters.'
%
(
self
.
name
,
type
(
value
)),
stacklevel
=
2
)
stacklevel
=
2
)
self
.
column_type_formatters
[
type
(
value
)]
=
lambda
_
,
value
:
type_fmt
(
value
)
self
.
column_type_formatters
[
type
(
value
)]
=
lambda
view
,
_model
,
_name
,
value
:
type_fmt
(
view
,
value
)
value
=
type_fmt
(
value
)
value
=
type_fmt
(
self
,
value
)
return
value
return
value
...
...
flask_admin/model/typefmt.py
View file @
fa757fc6
...
@@ -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
,
value
):
def
null_formatter
(
view
,
model
,
name
,
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, value):
...
@@ -12,7 +12,7 @@ def null_formatter(view, value):
return
Markup
(
'<i>NULL</i>'
)
return
Markup
(
'<i>NULL</i>'
)
def
empty_formatter
(
view
,
value
):
def
empty_formatter
(
view
,
model
,
name
,
value
):
"""
"""
Return empty string for `None` value
Return empty string for `None` value
...
@@ -22,7 +22,7 @@ def empty_formatter(view, value):
...
@@ -22,7 +22,7 @@ def empty_formatter(view, value):
return
''
return
''
def
bool_formatter
(
view
,
value
):
def
bool_formatter
(
view
,
model
,
name
,
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, value):
...
@@ -32,7 +32,7 @@ def bool_formatter(view, 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
,
values
):
def
list_formatter
(
view
,
model
,
name
,
values
):
"""
"""
Return string with comma separated values
Return string with comma separated values
...
...
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