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
f6132626
Commit
f6132626
authored
Jul 04, 2013
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
More complex inline model field example for SQLAlchemy
parent
b9eb2cca
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
195 additions
and
25 deletions
+195
-25
.gitignore
.gitignore
+1
-0
simple.py
examples/sqla-inline/simple.py
+130
-0
field_list.html
examples/sqla-inline/templates/field_list.html
+13
-0
locations.html
examples/sqla-inline/templates/locations.html
+12
-0
form.py
flask_admin/contrib/peeweemodel/form.py
+10
-7
form.py
flask_admin/contrib/sqlamodel/form.py
+16
-12
view.py
flask_admin/contrib/sqlamodel/view.py
+6
-6
form.py
flask_admin/model/form.py
+7
-0
No files found.
.gitignore
View file @
f6132626
...
...
@@ -15,3 +15,4 @@ venv
*.sublime-*
.coverage
__pycache__
examples/sqla-inline/static
examples/sqla-inline/simple.py
0 → 100644
View file @
f6132626
import
os
import
os.path
as
op
from
werkzeug
import
secure_filename
from
sqlalchemy
import
event
from
flask
import
Flask
,
request
,
render_template
from
flask.ext.sqlalchemy
import
SQLAlchemy
from
wtforms
import
fields
from
flask.ext
import
admin
from
flask.ext.admin.form
import
RenderTemplateWidget
from
flask.ext.admin.model.form
import
InlineFormAdmin
from
flask.ext.admin.contrib.sqlamodel
import
ModelView
from
flask.ext.admin.contrib.sqlamodel.form
import
InlineModelConverter
from
flask.ext.admin.contrib.sqlamodel.fields
import
InlineModelFormList
# Create application
app
=
Flask
(
__name__
)
# Create dummy secrey key so we can use sessions
app
.
config
[
'SECRET_KEY'
]
=
'123456790'
# Create in-memory database
app
.
config
[
'SQLALCHEMY_DATABASE_URI'
]
=
'sqlite:///test.sqlite'
app
.
config
[
'SQLALCHEMY_ECHO'
]
=
True
db
=
SQLAlchemy
(
app
)
# Figure out base upload path
base_path
=
op
.
join
(
op
.
dirname
(
__file__
),
'static'
)
# Create models
class
Location
(
db
.
Model
):
id
=
db
.
Column
(
db
.
Integer
,
primary_key
=
True
)
name
=
db
.
Column
(
db
.
Unicode
(
64
))
class
LocationImage
(
db
.
Model
):
id
=
db
.
Column
(
db
.
Integer
,
primary_key
=
True
)
alt
=
db
.
Column
(
db
.
Unicode
(
128
))
path
=
db
.
Column
(
db
.
String
(
64
))
location_id
=
db
.
Column
(
db
.
Integer
,
db
.
ForeignKey
(
Location
.
id
))
location
=
db
.
relation
(
Location
,
backref
=
'images'
)
# Register after_delete handler which will delete image file after model gets deleted
@
event
.
listens_for
(
LocationImage
,
'after_delete'
)
def
_handle_image_delete
(
mapper
,
conn
,
target
):
try
:
if
target
.
path
:
os
.
remove
(
op
.
join
(
base_path
,
target
.
path
))
except
:
pass
# This widget uses custom template for inline field list
class
CustomInlineFieldListWidget
(
RenderTemplateWidget
):
def
__init__
(
self
):
super
(
CustomInlineFieldListWidget
,
self
)
.
__init__
(
'field_list.html'
)
# This InlineModelFormList will use our custom widget
class
CustomInlineModelFormList
(
InlineModelFormList
):
widget
=
CustomInlineFieldListWidget
()
# Create custom InlineModelConverter and tell it to use our InlineModelFormList
class
CustomInlineModelConverter
(
InlineModelConverter
):
inline_field_list_type
=
CustomInlineModelFormList
# Customized inline form handler
class
InlineModelForm
(
InlineFormAdmin
):
form_excluded_columns
=
(
'path'
,)
form_label
=
'Image'
def
__init__
(
self
):
return
super
(
InlineModelForm
,
self
)
.
__init__
(
LocationImage
)
def
postprocess_form
(
self
,
form_class
):
form_class
.
upload
=
fields
.
FileField
(
'Image'
)
return
form_class
def
on_model_change
(
self
,
form
,
model
):
file_data
=
request
.
files
.
get
(
form
.
upload
.
name
)
if
file_data
:
model
.
path
=
secure_filename
(
file_data
.
filename
)
file_data
.
save
(
op
.
join
(
base_path
,
model
.
path
))
# Administrative class
class
LocationAdmin
(
ModelView
):
inline_model_form_converter
=
CustomInlineModelConverter
inline_models
=
(
InlineModelForm
(),)
def
__init__
(
self
):
super
(
LocationAdmin
,
self
)
.
__init__
(
Location
,
db
.
session
,
name
=
'Locations'
)
# Simple page to show images
@
app
.
route
(
'/'
)
def
index
():
locations
=
db
.
session
.
query
(
Location
)
.
all
()
return
render_template
(
'locations.html'
,
locations
=
locations
)
if
__name__
==
'__main__'
:
# Create upload directory
try
:
os
.
mkdir
(
base_path
)
except
OSError
:
pass
# Create admin
admin
=
admin
.
Admin
(
app
,
'Inline Fun'
)
# Add views
admin
.
add_view
(
LocationAdmin
())
# Create DB
db
.
create_all
()
# Start app
app
.
run
(
debug
=
True
)
examples/sqla-inline/templates/field_list.html
0 → 100644
View file @
f6132626
{% import 'admin/model/inline_list_base.html' as base with context %}
{% macro render_field(field) %}
{% set model = field.object_data %}
{% if model and model.path %}
{{ field.form.id }}
<img
src=
"{{ url_for('static', filename=model.path) }}"
style=
"max-width: 300px;"
></img>
{% else %}
{{ field }}
{% endif %}
{% endmacro %}
{{ base.render_inline_fields(field, template, render_field) }}
examples/sqla-inline/templates/locations.html
0 → 100644
View file @
f6132626
<html>
<body>
{% for loc in locations %}
<h2>
{{ loc.name }}
</h2>
{% for img in loc.images %}
<img
src=
"{{ url_for('static', filename=img.path) }}"
alt=
"{{ img.alt }}"
style=
"max-width: 300px"
></img>
{% endfor %}
<hr/>
{% endfor %}
<a
href=
"/admin"
>
Open admin to upload some images.
</a>
</body>
</html>
flask_admin/contrib/peeweemodel/form.py
View file @
f6132626
...
...
@@ -162,6 +162,9 @@ class InlineModelConverter(InlineModelConverterBase):
exclude
=
ignore
# Create field
child_form
=
info
.
get_form
()
if
child_form
is
None
:
child_form
=
model_form
(
info
.
model
,
base_class
=
form
.
BaseForm
,
only
=
info
.
form_columns
,
...
...
flask_admin/contrib/sqlamodel/form.py
View file @
f6132626
...
...
@@ -305,7 +305,8 @@ def _resolve_prop(prop):
# Get list of fields and generate form
def
get_form
(
model
,
converter
,
base_class
=
form
.
BaseForm
,
only
=
None
,
exclude
=
None
,
only
=
None
,
exclude
=
None
,
field_args
=
None
,
hidden_pk
=
False
,
ignore_hidden
=
True
):
...
...
@@ -473,11 +474,14 @@ class InlineModelConverter(InlineModelConverterBase):
ignore
=
[
reverse_prop
.
key
]
if
info
.
form_excluded_columns
:
exclude
=
ignore
+
info
.
form_excluded_columns
exclude
=
ignore
+
list
(
info
.
form_excluded_columns
)
else
:
exclude
=
ignore
# Create form
child_form
=
info
.
get_form
()
if
child_form
is
None
:
child_form
=
get_form
(
info
.
model
,
converter
,
only
=
info
.
form_columns
,
...
...
flask_admin/contrib/sqlamodel/view.py
View file @
f6132626
flask_admin/model/form.py
View file @
f6132626
...
...
@@ -41,6 +41,13 @@ class InlineFormAdmin(object):
for
k
,
v
in
iteritems
(
kwargs
):
setattr
(
self
,
k
,
v
)
def
get_form
(
self
):
"""
If you want to use completely custom form for inline field, you can override
Flask-Admin form generation logic by overriding this method and returning your form.
"""
return
None
def
postprocess_form
(
self
,
form_class
):
"""
Post process form. Use this to contribute fields.
...
...
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