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
48ebb0fc
Commit
48ebb0fc
authored
Dec 25, 2013
by
bryhoyt
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4 from mrjoes/master
Merge latest main repo into my local
parents
ee750e5c
9a87a0be
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
111 additions
and
44 deletions
+111
-44
sidebarintro.html
doc/_templates/sidebarintro.html
+1
-1
form.html
examples/auth-mongoengine/templates/form.html
+1
-1
simple.py
examples/layout/simple.py
+1
-0
fileadmin.py
flask_admin/contrib/fileadmin.py
+35
-10
filters.py
flask_admin/contrib/mongoengine/filters.py
+1
-1
subdoc.py
flask_admin/contrib/mongoengine/subdoc.py
+0
-8
fields.py
flask_admin/contrib/sqla/fields.py
+13
-2
tools.py
flask_admin/contrib/sqla/tools.py
+1
-1
form.py
flask_admin/model/form.py
+9
-1
filters.js
flask_admin/static/admin/js/filters.js
+1
-1
list.html
flask_admin/templates/admin/file/list.html
+4
-0
lib.html
flask_admin/templates/admin/lib.html
+7
-6
inline_list_base.html
flask_admin/templates/admin/model/inline_list_base.html
+10
-4
list.html
flask_admin/templates/admin/model/list.html
+8
-8
test_form_rules.py
flask_admin/tests/sqlamodel/test_form_rules.py
+19
-0
No files found.
doc/_templates/sidebarintro.html
View file @
48ebb0fc
...
...
@@ -5,4 +5,4 @@
</ul>
<a
href=
"http://github.com/mrjoes/flask-admin"
><img
style=
"position: fixed; top: 0; right: 0; border: 0;"
src=
"
http:
//s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"
alt=
"Fork me on GitHub"
/></a>
src=
"//s3.amazonaws.com/github/ribbons/forkme_right_darkblue_121621.png"
alt=
"Fork me on GitHub"
/></a>
examples/auth-mongoengine/templates/form.html
View file @
48ebb0fc
...
...
@@ -8,7 +8,7 @@
{{ f }}
{% if f.errors %}
<ul>
{% for e in f.err
r
ors %}
{% for e in f.errors %}
<li>
{{ e }}
</li>
{% endfor %}
</ul>
...
...
examples/layout/simple.py
View file @
48ebb0fc
import
os
import
os.path
as
op
from
flask
import
Flask
from
flask.ext.sqlalchemy
import
SQLAlchemy
...
...
flask_admin/contrib/fileadmin.py
View file @
48ebb0fc
...
...
@@ -7,7 +7,7 @@ import shutil
from
operator
import
itemgetter
from
werkzeug
import
secure_filename
from
flask
import
flash
,
url_for
,
redirect
,
abort
,
request
from
flask
import
flash
,
url_for
,
redirect
,
abort
,
request
,
send_file
from
wtforms
import
fields
,
validators
...
...
@@ -64,13 +64,12 @@ class FileAdmin(BaseView, ActionsMixin):
"""
Simple file-management interface.
Requires two parameters:
:param path:
Path to the directory which will be managed
:param url:
Base URL for the directory. Will be used to generate
static links to the files.
:param base_url:
Optional base URL for the directory. Will be used to generate
static links to the files. If not defined, a route will be created
to serve uploaded files.
Sample usage::
...
...
@@ -86,6 +85,11 @@ class FileAdmin(BaseView, ActionsMixin):
Is file upload allowed.
"""
can_download
=
True
"""
Is file download allowed.
"""
can_delete
=
True
"""
Is file deletion allowed.
...
...
@@ -151,7 +155,7 @@ class FileAdmin(BaseView, ActionsMixin):
Edit template
"""
def
__init__
(
self
,
base_path
,
base_url
,
def
__init__
(
self
,
base_path
,
base_url
=
None
,
name
=
None
,
category
=
None
,
endpoint
=
None
,
url
=
None
,
verify_path
=
True
):
"""
...
...
@@ -310,10 +314,10 @@ class FileAdmin(BaseView, ActionsMixin):
Static file path
"""
if
self
.
is_file_editable
(
path
):
r
eturn
url_for
(
".edit"
,
path
=
path
)
r
oute
=
'.edit'
else
:
base_url
=
self
.
get_base_url
()
return
urljoin
(
base_url
,
path
)
route
=
'.download'
return
url_for
(
route
,
path
=
path
)
def
_normalize_path
(
self
,
path
):
"""
...
...
@@ -503,6 +507,27 @@ class FileAdmin(BaseView, ActionsMixin):
return
self
.
render
(
self
.
upload_template
,
form
=
form
)
@
expose
(
'/download/<path:path>'
)
def
download
(
self
,
path
=
None
):
"""
Download view method.
:param path:
File path.
"""
if
not
self
.
can_download
:
abort
(
404
)
base_path
,
directory
,
path
=
self
.
_normalize_path
(
path
)
# backward compatibility with base_url
base_url
=
self
.
get_base_url
()
if
base_url
:
base_url
=
urljoin
(
url_for
(
'.index'
),
base_url
)
return
redirect
(
urljoin
(
base_url
,
path
))
return
send_file
(
directory
)
@
expose
(
'/mkdir/'
,
methods
=
(
'GET'
,
'POST'
))
@
expose
(
'/mkdir/<path:path>'
,
methods
=
(
'GET'
,
'POST'
))
def
mkdir
(
self
,
path
=
None
):
...
...
flask_admin/contrib/mongoengine/filters.py
View file @
48ebb0fc
...
...
@@ -107,7 +107,7 @@ class FilterConverter(filters.BaseFilterConverter):
return
None
@
filters
.
convert
(
'StringField'
)
@
filters
.
convert
(
'StringField'
,
'EmailField'
)
def
conv_string
(
self
,
column
,
name
):
return
[
f
(
column
,
name
)
for
f
in
self
.
strings
]
...
...
flask_admin/contrib/mongoengine/subdoc.py
View file @
48ebb0fc
from
flask.ext.admin._compat
import
iteritems
from
flask.ext.admin.form
import
rules
from
flask.ext.admin.model.form
import
InlineBaseFormAdmin
...
...
@@ -9,13 +8,6 @@ class EmbeddedForm(InlineBaseFormAdmin):
self
.
_form_subdocuments
=
convert_subdocuments
(
getattr
(
self
,
'form_subdocuments'
,
{}))
form_rules
=
getattr
(
self
,
'form_rules'
,
None
)
if
form_rules
:
self
.
_form_rules
=
rules
.
RuleSet
(
self
,
form_rules
)
else
:
self
.
_form_rules
=
None
def
convert_subdocuments
(
values
):
result
=
{}
...
...
flask_admin/contrib/sqla/fields.py
View file @
48ebb0fc
...
...
@@ -9,7 +9,9 @@ from wtforms.validators import ValidationError
from
.tools
import
get_primary_key
from
flask.ext.admin._compat
import
text_type
,
string_types
from
flask.ext.admin.form
import
FormOpts
from
flask.ext.admin.model.fields
import
InlineFieldList
,
InlineModelFormField
from
flask.ext.admin.model.widgets
import
InlineFormWidget
try
:
...
...
@@ -186,7 +188,7 @@ class InlineModelFormList(InlineFieldList):
Form field type. Override to use custom field for each inline form
"""
def
__init__
(
self
,
form
,
session
,
model
,
prop
,
inline_view
,
**
kwargs
):
def
__init__
(
self
,
form
,
session
,
model
,
prop
,
inline_view
,
form_widget
=
None
,
**
kwargs
):
"""
Default constructor.
...
...
@@ -209,7 +211,16 @@ class InlineModelFormList(InlineFieldList):
self
.
_pk
=
get_primary_key
(
model
)
super
(
InlineModelFormList
,
self
)
.
__init__
(
self
.
form_field_type
(
form
,
self
.
_pk
),
**
kwargs
)
# Generate inline form field
if
form_widget
is
None
:
form_opts
=
FormOpts
(
widget_args
=
getattr
(
inline_view
,
'form_widget_args'
,
None
),
form_rules
=
inline_view
.
_form_rules
)
form_widget
=
InlineFormWidget
(
form_opts
)
form_field
=
self
.
form_field_type
(
form
,
self
.
_pk
,
widget
=
form_widget
)
super
(
InlineModelFormList
,
self
)
.
__init__
(
form_field
,
**
kwargs
)
def
display_row_controls
(
self
,
field
):
return
field
.
get_pk
()
is
not
None
...
...
flask_admin/contrib/sqla/tools.py
View file @
48ebb0fc
...
...
@@ -31,7 +31,7 @@ def get_primary_key(model):
if
is_inherited_primary_key
(
p
):
pks
.
append
(
get_column_for_current_model
(
p
)
.
key
)
else
:
pks
.
append
(
p
.
columns
[
0
]
.
key
)
pks
.
append
(
p
.
key
)
if
len
(
pks
)
==
1
:
return
pks
[
0
]
elif
len
(
pks
)
>
1
:
...
...
flask_admin/model/form.py
View file @
48ebb0fc
import
inspect
from
flask.ext.admin.form
import
BaseForm
from
flask.ext.admin.form
import
BaseForm
,
rules
from
flask.ext.admin._compat
import
iteritems
...
...
@@ -37,6 +37,14 @@ class InlineBaseFormAdmin(object):
for
k
,
v
in
iteritems
(
kwargs
):
setattr
(
self
,
k
,
v
)
# Convert form rules
form_rules
=
getattr
(
self
,
'form_rules'
,
None
)
if
form_rules
:
self
.
_form_rules
=
rules
.
RuleSet
(
self
,
form_rules
)
else
:
self
.
_form_rules
=
None
def
get_form
(
self
):
"""
If you want to use completely custom form for inline field, you can override
...
...
flask_admin/static/admin/js/filters.js
View file @
48ebb0fc
...
...
@@ -10,7 +10,7 @@ var AdminFilters = function(element, filters_element, filters_by_group) {
function
changeOperation
()
{
var
$row
=
$
(
this
).
closest
(
'tr'
);
var
$el
=
$
(
'.filter-val'
,
$row
);
var
$el
=
$
(
'.filter-val
:input
'
,
$row
);
var
count
=
getCount
(
$el
.
attr
(
'name'
));
$el
.
attr
(
'name'
,
'flt'
+
count
+
'_'
+
$
(
this
).
val
());
$
(
'button'
,
$root
).
show
();
...
...
flask_admin/templates/admin/file/list.html
View file @
48ebb0fc
...
...
@@ -83,7 +83,11 @@
</td>
{% else %}
<td>
{% if admin_view.can_download %}
<a
href=
"{{ get_file_url(path)|safe }}"
>
{{ name }}
</a>
{% else %}
{{ name }}
{% endif %}
</td>
<td>
{{ size }}
...
...
flask_admin/templates/admin/lib.html
View file @
48ebb0fc
...
...
@@ -79,12 +79,13 @@
{% set direct_error = h.is_field_error(field.errors) %}
<div
class=
"control-group{{ ' error' if direct_error else '' }}"
>
<div
class=
"control-label"
>
{{ field.label.text }}
{% if h.is_required_form_field(field) %}
<strong
style=
"color: red"
>
*
</strong>
{% else %}
{% endif %}
<label
for=
"{{ field.id }}"
>
{{ field.label.text }}
{% if h.is_required_form_field(field) %}
<strong
style=
"color: red"
>
*
</strong>
{%- else -%}
{%- endif %}
</label>
</div>
<div
class=
"controls"
>
<div>
...
...
flask_admin/templates/admin/model/inline_list_base.html
View file @
48ebb0fc
...
...
@@ -4,10 +4,16 @@
{% for subfield in field %}
<div
id=
"{{ subfield.id }}"
class=
"fa-inline-field"
>
{%- if not check or check(subfield) %}
<div
class=
"fa-inline-field-control"
>
<input
type=
"checkbox"
name=
"del-{{ subfield.id }}"
id=
"del-{{ subfield.id }}"
/>
<label
for=
"del-{{ subfield.id }}"
style=
"display: inline"
>
{{ _gettext('Delete?') }}
</label>
</div>
{% if subfield.get_pk and subfield.get_pk() %}
<div
class=
"fa-inline-field-control"
>
<input
type=
"checkbox"
name=
"del-{{ subfield.id }}"
id=
"del-{{ subfield.id }}"
/>
<label
for=
"del-{{ subfield.id }}"
style=
"display: inline"
>
{{ _gettext('Delete?') }}
</label>
</div>
{% else %}
<div
class=
"fa-inline-field-control"
>
<a
href=
"javascript:void(0)"
class=
"fa-remove-field"
><i
class=
"icon-remove"
></i></a>
</div>
{% endif %}
{%- endif -%}
{{ render(subfield) }}
...
...
flask_admin/templates/admin/model/list.html
View file @
48ebb0fc
...
...
@@ -18,7 +18,7 @@
</li>
{% if admin_view.can_create %}
<li>
<a
href=
"{{ url_for('.create_view', url=return_url) }}"
>
{{ _gettext('Create') }}
</a>
<a
href=
"{{ url_for('.create_view', url=return_url) }}"
title=
"{{ _gettext('Create new record') }}"
>
{{ _gettext('Create') }}
</a>
</li>
{% endif %}
...
...
@@ -54,7 +54,7 @@
{% block list_header scoped %}
{% if actions %}
<th
class=
"span1"
>
<input
type=
"checkbox"
name=
"rowtoggle"
class=
"action-rowtoggle"
/>
<input
type=
"checkbox"
name=
"rowtoggle"
class=
"action-rowtoggle"
title=
"{{ _gettext('Select all records') }}"
/>
</th>
{% endif %}
{% block list_row_actions_header %}
...
...
@@ -62,10 +62,10 @@
{% endblock %}
{% set column = 0 %}
{% for c, name in list_columns %}
<th>
<th
class=
"column-header"
>
{% if admin_view.is_sortable(c) %}
{% if sort_column == column %}
<a
href=
"{{ sort_url(column, True) }}"
>
<a
href=
"{{ sort_url(column, True) }}"
title=
"{{ _gettext('Sort by %(name)s', name=name) }}"
>
{{ name }}
{% if sort_desc %}
<i
class=
"icon-chevron-up"
></i>
...
...
@@ -74,7 +74,7 @@
{% endif %}
</a>
{% else %}
<a
href=
"{{ sort_url(column) }}"
>
{{ name }}
</a>
<a
href=
"{{ sort_url(column) }}"
title=
"{{ _gettext('Sort by %(name)s', name=name) }}"
>
{{ name }}
</a>
{% endif %}
{% else %}
{{ name }}
...
...
@@ -96,13 +96,13 @@
{% block list_row scoped %}
{% if actions %}
<td>
<input
type=
"checkbox"
name=
"rowid"
class=
"action-checkbox"
value=
"{{ get_pk_value(row) }}"
/>
<input
type=
"checkbox"
name=
"rowid"
class=
"action-checkbox"
value=
"{{ get_pk_value(row) }}"
title=
"{{ _gettext('Select record') }}"
/>
</td>
{% endif %}
<td>
{% block list_row_actions scoped %}
{%- if admin_view.can_edit -%}
<a
class=
"icon"
href=
"{{ url_for('.edit_view', id=get_pk_value(row), url=return_url) }}"
>
<a
class=
"icon"
href=
"{{ url_for('.edit_view', id=get_pk_value(row), url=return_url) }}"
title=
"Edit record"
>
<i
class=
"icon-pencil"
></i>
</a>
{%- endif -%}
...
...
@@ -111,7 +111,7 @@
{% if csrf_token %}
<input
type=
"hidden"
name=
"csrf_token"
value=
"{{ csrf_token() }}"
/>
{% endif %}
<button
onclick=
"return confirm('{{ _gettext('You sure you want to delete this item?') }}');"
>
<button
onclick=
"return confirm('{{ _gettext('You sure you want to delete this item?') }}');"
title=
"Delete record"
>
<i
class=
"icon-trash"
></i>
</button>
</form>
...
...
flask_admin/tests/sqlamodel/test_form_rules.py
View file @
48ebb0fc
...
...
@@ -139,3 +139,22 @@ def test_rule_inlinefieldlist():
rv
=
client
.
get
(
'/admin/model1view/new/'
)
eq_
(
rv
.
status_code
,
200
)
def
test_inline_model_rules
():
app
,
db
,
admin
=
setup
()
Model1
,
Model2
=
create_models
(
db
)
db
.
create_all
()
view
=
CustomModelView
(
Model1
,
db
.
session
,
inline_models
=
[(
Model2
,
dict
(
form_rules
=
(
'string_field'
,
'bool_field'
)))])
admin
.
add_view
(
view
)
client
=
app
.
test_client
()
rv
=
client
.
get
(
'/admin/model1view/new/'
)
eq_
(
rv
.
status_code
,
200
)
data
=
rv
.
data
.
decode
(
'utf-8'
)
ok_
(
'int_field'
not
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