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
ee46f523
Commit
ee46f523
authored
Apr 10, 2012
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added localization support through Flask-Babel.
parent
cf4179ad
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
132 additions
and
74 deletions
+132
-74
TODO.txt
TODO.txt
+6
-8
babel.py
flask_adminex/babel.py
+45
-0
base.py
flask_adminex/base.py
+7
-3
fileadmin.py
flask_adminex/ext/fileadmin.py
+24
-23
filters.py
flask_adminex/ext/sqlamodel/filters.py
+8
-6
view.py
flask_adminex/ext/sqlamodel/view.py
+4
-3
form.py
flask_adminex/form.py
+3
-1
base.py
flask_adminex/model/base.py
+3
-1
filters.py
flask_adminex/model/filters.py
+5
-1
form.html
flask_adminex/templates/admin/file/form.html
+1
-1
list.html
flask_adminex/templates/admin/file/list.html
+6
-6
rename.html
flask_adminex/templates/admin/file/rename.html
+2
-2
lib.html
flask_adminex/templates/admin/lib.html
+1
-1
create.html
flask_adminex/templates/admin/model/create.html
+3
-3
edit.html
flask_adminex/templates/admin/model/edit.html
+1
-1
list.html
flask_adminex/templates/admin/model/list.html
+10
-10
test_base.py
flask_adminex/tests/test_base.py
+0
-1
test_sqlamodel.py
flask_adminex/tests/test_sqlamodel.py
+2
-2
setup.py
setup.py
+1
-1
No files found.
TODO.txt
View file @
ee46f523
- Core
- Core
- View Site button?
- View Site button?
- Localization
- Model Admin
- Model Admin
- Ability to sort by fields that are not visible?
- Reduce number of parameters passed to list view
- List display callables
- Checkboxes and mass operations
- Form Fields
- Override field class by field name
- Verify how boolean field is rendered
- Filters
- Filters
- Custom filters for date fields?
- Custom filters for date fields?
- Checkboxes and mass operations
- Ability to sort by fields that are not visible?
- List display callables?
- SQLA Model Admin
- SQLA Model Admin
- Many2Many support
- Many2Many support
- Verify if it is working properly
- Verify if it is working properly
...
@@ -17,8 +16,7 @@
...
@@ -17,8 +16,7 @@
- Header title
- Header title
- Mass-delete functionality
- Mass-delete functionality
- File size restriction
- File size restriction
- Localization
- Unit tests
- Unit tests
- Form generation tests
- Form generation tests
- Documentation
- Documentation
- Add all new stuff
- Add all new stuff
\ No newline at end of file
flask_adminex/babel.py
0 → 100644
View file @
ee46f523
from
flask
import
_request_ctx_stack
def
_gettext
(
string
,
**
variables
):
return
string
%
variables
def
_ngettext
(
singular
,
plural
,
num
,
**
variables
):
return
(
singular
if
num
==
1
else
plural
)
%
variables
def
_lazy_gettext
(
string
,
**
variables
):
return
string
%
variables
# Wrap flask-babel API
try
:
from
flask.ext
import
babel
def
_is_babel_on
():
ctx
=
_request_ctx_stack
.
top
if
ctx
is
None
:
return
False
return
hasattr
(
ctx
,
'babel_locale'
)
def
gettext
(
string
,
**
variables
):
if
not
_is_babel_on
():
return
_gettext
(
string
,
**
variables
)
return
babel
.
gettext
(
string
,
**
variables
)
def
ngettext
(
singular
,
plural
,
num
,
**
variables
):
if
not
_is_babel_on
():
return
_ngettext
(
singular
,
plural
,
num
,
**
variables
)
return
babel
.
ngettext
(
singular
,
plural
,
num
,
**
variables
)
def
lazy_gettext
(
string
,
**
variables
):
from
speaklater
import
make_lazy_string
return
make_lazy_string
(
gettext
,
string
,
**
variables
)
except
ImportError
:
gettext
=
_gettext
ngettext
=
_ngettext
lazy_gettext
=
_lazy_gettext
flask_adminex/base.py
View file @
ee46f523
...
@@ -3,6 +3,8 @@ from re import sub
...
@@ -3,6 +3,8 @@ from re import sub
from
flask
import
Blueprint
,
render_template
,
url_for
,
abort
from
flask
import
Blueprint
,
render_template
,
url_for
,
abort
from
flask.ext.adminex
import
babel
def
expose
(
url
=
'/'
,
methods
=
(
'GET'
,)):
def
expose
(
url
=
'/'
,
methods
=
(
'GET'
,)):
"""
"""
...
@@ -159,6 +161,11 @@ class BaseView(object):
...
@@ -159,6 +161,11 @@ class BaseView(object):
# Store self as admin_view
# Store self as admin_view
kwargs
[
'admin_view'
]
=
self
kwargs
[
'admin_view'
]
=
self
# Provide i18n support even if flask-babel is not installed
# or enabled.
kwargs
[
'_gettext'
]
=
babel
.
gettext
kwargs
[
'_ngettext'
]
=
babel
.
ngettext
return
render_template
(
template
,
**
kwargs
)
return
render_template
(
template
,
**
kwargs
)
def
_prettify_name
(
self
,
name
):
def
_prettify_name
(
self
,
name
):
...
@@ -260,9 +267,6 @@ class MenuItem(object):
...
@@ -260,9 +267,6 @@ class MenuItem(object):
def
get_children
(
self
):
def
get_children
(
self
):
return
[
c
for
c
in
self
.
_children
if
c
.
is_accessible
()]
return
[
c
for
c
in
self
.
_children
if
c
.
is_accessible
()]
def
__repr__
(
self
):
return
'MenuItem
%
s (
%
s)'
%
(
self
.
name
,
repr
(
self
.
_children
))
class
Admin
(
object
):
class
Admin
(
object
):
"""
"""
...
...
flask_adminex/ext/fileadmin.py
View file @
ee46f523
...
@@ -7,11 +7,12 @@ import shutil
...
@@ -7,11 +7,12 @@ import shutil
from
operator
import
itemgetter
from
operator
import
itemgetter
from
flask
import
flash
,
url_for
,
redirect
,
abort
,
request
from
werkzeug
import
secure_filename
from
werkzeug
import
secure_filename
from
flask
import
flash
,
url_for
,
redirect
,
abort
,
request
from
flask.ext.adminex.base
import
BaseView
,
expose
from
flask.ext.adminex.base
import
BaseView
,
expose
from
flask.ext.adminex.babel
import
gettext
,
lazy_gettext
from
flask.ext.adminex
import
form
from
flask.ext.adminex
import
form
from
flask.ext
import
wtf
from
flask.ext
import
wtf
...
@@ -28,7 +29,7 @@ class NameForm(form.BaseForm):
...
@@ -28,7 +29,7 @@ class NameForm(form.BaseForm):
def
validate_name
(
self
,
field
):
def
validate_name
(
self
,
field
):
if
not
self
.
regexp
.
match
(
field
.
data
):
if
not
self
.
regexp
.
match
(
field
.
data
):
raise
wtf
.
ValidationError
(
'Invalid directory name'
)
raise
wtf
.
ValidationError
(
gettext
(
'Invalid directory name'
)
)
class
UploadForm
(
form
.
BaseForm
):
class
UploadForm
(
form
.
BaseForm
):
...
@@ -36,7 +37,7 @@ class UploadForm(form.BaseForm):
...
@@ -36,7 +37,7 @@ class UploadForm(form.BaseForm):
File upload form. Works with FileAdmin instance to check if it is allowed
File upload form. Works with FileAdmin instance to check if it is allowed
to upload file with given extension.
to upload file with given extension.
"""
"""
upload
=
wtf
.
FileField
(
'File to upload'
)
upload
=
wtf
.
FileField
(
lazy_gettext
(
'File to upload'
)
)
def
__init__
(
self
,
admin
):
def
__init__
(
self
,
admin
):
self
.
admin
=
admin
self
.
admin
=
admin
...
@@ -45,12 +46,12 @@ class UploadForm(form.BaseForm):
...
@@ -45,12 +46,12 @@ class UploadForm(form.BaseForm):
def
validate_upload
(
self
,
field
):
def
validate_upload
(
self
,
field
):
if
not
self
.
upload
.
has_file
():
if
not
self
.
upload
.
has_file
():
raise
wtf
.
ValidationError
(
'File required.'
)
raise
wtf
.
ValidationError
(
gettext
(
'File required.'
)
)
filename
=
self
.
upload
.
data
.
filename
filename
=
self
.
upload
.
data
.
filename
if
not
self
.
admin
.
is_file_allowed
(
filename
):
if
not
self
.
admin
.
is_file_allowed
(
filename
):
raise
wtf
.
ValidationError
(
'Invalid file type.'
)
raise
wtf
.
ValidationError
(
gettext
(
'Invalid file type.'
)
)
class
FileAdmin
(
BaseView
):
class
FileAdmin
(
BaseView
):
...
@@ -331,7 +332,7 @@ class FileAdmin(BaseView):
...
@@ -331,7 +332,7 @@ class FileAdmin(BaseView):
base_path
,
directory
,
path
=
self
.
_normalize_path
(
path
)
base_path
,
directory
,
path
=
self
.
_normalize_path
(
path
)
if
not
self
.
can_upload
:
if
not
self
.
can_upload
:
flash
(
'File uploading is disabled.'
,
'error'
)
flash
(
gettext
(
'File uploading is disabled.'
)
,
'error'
)
return
redirect
(
self
.
_get_dir_url
(
'.index'
,
path
))
return
redirect
(
self
.
_get_dir_url
(
'.index'
,
path
))
form
=
UploadForm
(
self
)
form
=
UploadForm
(
self
)
...
@@ -340,14 +341,14 @@ class FileAdmin(BaseView):
...
@@ -340,14 +341,14 @@ class FileAdmin(BaseView):
secure_filename
(
form
.
upload
.
data
.
filename
))
secure_filename
(
form
.
upload
.
data
.
filename
))
if
op
.
exists
(
filename
):
if
op
.
exists
(
filename
):
flash
(
'File "
%
s" already exists.'
%
form
.
upload
.
data
.
filename
,
flash
(
gettext
(
'File "
%(name)
s" already exists.'
,
name
=
form
.
upload
.
data
.
filename
)
,
'error'
)
'error'
)
else
:
else
:
try
:
try
:
self
.
save_file
(
filename
,
form
.
upload
.
data
)
self
.
save_file
(
filename
,
form
.
upload
.
data
)
return
redirect
(
self
.
_get_dir_url
(
'.index'
,
path
))
return
redirect
(
self
.
_get_dir_url
(
'.index'
,
path
))
except
Exception
,
ex
:
except
Exception
,
ex
:
flash
(
'Failed to save file:
%
s'
%
ex
)
flash
(
gettext
(
'Failed to save file:
%(error)
s'
,
error
=
ex
)
)
return
self
.
render
(
self
.
upload_template
,
form
=
form
)
return
self
.
render
(
self
.
upload_template
,
form
=
form
)
...
@@ -366,7 +367,7 @@ class FileAdmin(BaseView):
...
@@ -366,7 +367,7 @@ class FileAdmin(BaseView):
dir_url
=
self
.
_get_dir_url
(
'.index'
,
path
)
dir_url
=
self
.
_get_dir_url
(
'.index'
,
path
)
if
not
self
.
can_mkdir
:
if
not
self
.
can_mkdir
:
flash
(
'Directory creation is disabled.'
,
'error'
)
flash
(
gettext
(
'Directory creation is disabled.'
)
,
'error'
)
return
redirect
(
dir_url
)
return
redirect
(
dir_url
)
form
=
NameForm
(
request
.
form
)
form
=
NameForm
(
request
.
form
)
...
@@ -376,7 +377,7 @@ class FileAdmin(BaseView):
...
@@ -376,7 +377,7 @@ class FileAdmin(BaseView):
os
.
mkdir
(
op
.
join
(
directory
,
form
.
name
.
data
))
os
.
mkdir
(
op
.
join
(
directory
,
form
.
name
.
data
))
return
redirect
(
dir_url
)
return
redirect
(
dir_url
)
except
Exception
,
ex
:
except
Exception
,
ex
:
flash
(
'Failed to create directory:
%
s'
%
ex
,
'error'
)
flash
(
gettext
(
'Failed to create directory:
%(error)
s'
,
ex
)
,
'error'
)
return
self
.
render
(
self
.
mkdir_template
,
return
self
.
render
(
self
.
mkdir_template
,
form
=
form
,
form
=
form
,
...
@@ -398,25 +399,25 @@ class FileAdmin(BaseView):
...
@@ -398,25 +399,25 @@ class FileAdmin(BaseView):
return_url
=
self
.
_get_dir_url
(
'.index'
,
op
.
dirname
(
path
))
return_url
=
self
.
_get_dir_url
(
'.index'
,
op
.
dirname
(
path
))
if
not
self
.
can_delete
:
if
not
self
.
can_delete
:
flash
(
'Deletion is disabled.'
)
flash
(
gettext
(
'Deletion is disabled.'
)
)
return
redirect
(
return_url
)
return
redirect
(
return_url
)
if
op
.
isdir
(
full_path
):
if
op
.
isdir
(
full_path
):
if
not
self
.
can_delete_dirs
:
if
not
self
.
can_delete_dirs
:
flash
(
'Directory deletion is disabled.'
)
flash
(
gettext
(
'Directory deletion is disabled.'
)
)
return
redirect
(
return_url
)
return
redirect
(
return_url
)
try
:
try
:
shutil
.
rmtree
(
full_path
)
shutil
.
rmtree
(
full_path
)
flash
(
'Directory "
%
s" was successfully deleted.'
%
path
)
flash
(
gettext
(
'Directory "
%
s" was successfully deleted.'
%
path
)
)
except
Exception
,
ex
:
except
Exception
,
ex
:
flash
(
'Failed to delete directory:
%
s'
%
ex
,
'error'
)
flash
(
gettext
(
'Failed to delete directory:
%(error)
s'
,
error
=
ex
)
,
'error'
)
else
:
else
:
try
:
try
:
os
.
remove
(
full_path
)
os
.
remove
(
full_path
)
flash
(
'File "
%
s" was successfully deleted.'
%
path
)
flash
(
gettext
(
'File "
%(name)
s" was successfully deleted.'
,
name
=
path
)
)
except
Exception
,
ex
:
except
Exception
,
ex
:
flash
(
'Failed to delete file:
%
s'
%
ex
,
'error'
)
flash
(
gettext
(
'Failed to delete file:
%(name)
s'
,
name
=
ex
)
,
'error'
)
return
redirect
(
return_url
)
return
redirect
(
return_url
)
...
@@ -435,11 +436,11 @@ class FileAdmin(BaseView):
...
@@ -435,11 +436,11 @@ class FileAdmin(BaseView):
return_url
=
self
.
_get_dir_url
(
'.index'
,
op
.
dirname
(
path
))
return_url
=
self
.
_get_dir_url
(
'.index'
,
op
.
dirname
(
path
))
if
not
self
.
can_rename
:
if
not
self
.
can_rename
:
flash
(
'Renaming is disabled.'
)
flash
(
gettext
(
'Renaming is disabled.'
)
)
return
redirect
(
return_url
)
return
redirect
(
return_url
)
if
not
op
.
exists
(
full_path
):
if
not
op
.
exists
(
full_path
):
flash
(
'Path does not exist.'
)
flash
(
gettext
(
'Path does not exist.'
)
)
return
redirect
(
return_url
)
return
redirect
(
return_url
)
form
=
NameForm
(
request
.
form
,
name
=
op
.
basename
(
path
))
form
=
NameForm
(
request
.
form
,
name
=
op
.
basename
(
path
))
...
@@ -449,11 +450,11 @@ class FileAdmin(BaseView):
...
@@ -449,11 +450,11 @@ class FileAdmin(BaseView):
filename
=
secure_filename
(
form
.
name
.
data
)
filename
=
secure_filename
(
form
.
name
.
data
)
os
.
rename
(
full_path
,
op
.
join
(
dir_base
,
filename
))
os
.
rename
(
full_path
,
op
.
join
(
dir_base
,
filename
))
flash
(
'Successfully renamed "
%
s" to "
%
s"'
%
(
flash
(
gettext
(
'Successfully renamed "
%(src)
s" to "
%(dst)
s"'
,
op
.
basename
(
path
),
src
=
op
.
basename
(
path
),
filename
))
dst
=
filename
))
except
Exception
,
ex
:
except
Exception
,
ex
:
flash
(
'Failed to rename:
%
s'
%
ex
,
'error'
)
flash
(
gettext
(
'Failed to rename:
%(error)
s'
,
error
=
ex
)
,
'error'
)
return
redirect
(
return_url
)
return
redirect
(
return_url
)
...
...
flask_adminex/ext/sqlamodel/filters.py
View file @
ee46f523
from
flask.ext.babel
import
gettext
from
flask.ext.adminex.model
import
filters
from
flask.ext.adminex.model
import
filters
from
flask.ext.adminex.ext.sqlamodel
import
tools
from
flask.ext.adminex.ext.sqlamodel
import
tools
...
@@ -30,7 +32,7 @@ class FilterEqual(BaseSQLAFilter):
...
@@ -30,7 +32,7 @@ class FilterEqual(BaseSQLAFilter):
return
query
.
filter
(
self
.
column
==
value
)
return
query
.
filter
(
self
.
column
==
value
)
def
operation
(
self
):
def
operation
(
self
):
return
'equals'
return
gettext
(
'equals'
)
class
FilterNotEqual
(
BaseSQLAFilter
):
class
FilterNotEqual
(
BaseSQLAFilter
):
...
@@ -38,7 +40,7 @@ class FilterNotEqual(BaseSQLAFilter):
...
@@ -38,7 +40,7 @@ class FilterNotEqual(BaseSQLAFilter):
return
query
.
filter
(
self
.
column
!=
value
)
return
query
.
filter
(
self
.
column
!=
value
)
def
operation
(
self
):
def
operation
(
self
):
return
'not equal'
return
gettext
(
'not equal'
)
class
FilterLike
(
BaseSQLAFilter
):
class
FilterLike
(
BaseSQLAFilter
):
...
@@ -47,7 +49,7 @@ class FilterLike(BaseSQLAFilter):
...
@@ -47,7 +49,7 @@ class FilterLike(BaseSQLAFilter):
return
query
.
filter
(
self
.
column
.
ilike
(
stmt
))
return
query
.
filter
(
self
.
column
.
ilike
(
stmt
))
def
operation
(
self
):
def
operation
(
self
):
return
'like'
return
gettext
(
'contains'
)
class
FilterNotLike
(
BaseSQLAFilter
):
class
FilterNotLike
(
BaseSQLAFilter
):
...
@@ -56,7 +58,7 @@ class FilterNotLike(BaseSQLAFilter):
...
@@ -56,7 +58,7 @@ class FilterNotLike(BaseSQLAFilter):
return
query
.
filter
(
~
self
.
column
.
ilike
(
stmt
))
return
query
.
filter
(
~
self
.
column
.
ilike
(
stmt
))
def
operation
(
self
):
def
operation
(
self
):
return
'not like'
return
gettext
(
'not contains'
)
class
FilterGreater
(
BaseSQLAFilter
):
class
FilterGreater
(
BaseSQLAFilter
):
...
@@ -64,7 +66,7 @@ class FilterGreater(BaseSQLAFilter):
...
@@ -64,7 +66,7 @@ class FilterGreater(BaseSQLAFilter):
return
query
.
filter
(
self
.
column
>
value
)
return
query
.
filter
(
self
.
column
>
value
)
def
operation
(
self
):
def
operation
(
self
):
return
'greater than'
return
gettext
(
'greater than'
)
class
FilterSmaller
(
BaseSQLAFilter
):
class
FilterSmaller
(
BaseSQLAFilter
):
...
@@ -72,7 +74,7 @@ class FilterSmaller(BaseSQLAFilter):
...
@@ -72,7 +74,7 @@ class FilterSmaller(BaseSQLAFilter):
return
query
.
filter
(
self
.
column
<
value
)
return
query
.
filter
(
self
.
column
<
value
)
def
operation
(
self
):
def
operation
(
self
):
return
'smaller than'
return
gettext
(
'smaller than'
)
# Customized type filters
# Customized type filters
...
...
flask_adminex/ext/sqlamodel/view.py
View file @
ee46f523
...
@@ -6,6 +6,7 @@ from sqlalchemy import or_
...
@@ -6,6 +6,7 @@ from sqlalchemy import or_
from
wtforms.ext.sqlalchemy.orm
import
model_form
from
wtforms.ext.sqlalchemy.orm
import
model_form
from
flask
import
flash
from
flask
import
flash
from
flask.ext.babel
import
gettext
from
flask.ext.adminex.form
import
BaseForm
from
flask.ext.adminex.form
import
BaseForm
from
flask.ext.adminex.model
import
BaseModelView
from
flask.ext.adminex.model
import
BaseModelView
...
@@ -500,7 +501,7 @@ class ModelView(BaseModelView):
...
@@ -500,7 +501,7 @@ class ModelView(BaseModelView):
self
.
session
.
commit
()
self
.
session
.
commit
()
return
True
return
True
except
Exception
,
ex
:
except
Exception
,
ex
:
flash
(
'Failed to create model. '
+
str
(
ex
),
'error'
)
flash
(
gettext
(
'Failed to create model.
%(error)
s'
,
error
=
str
(
ex
)
),
'error'
)
return
False
return
False
def
update_model
(
self
,
form
,
model
):
def
update_model
(
self
,
form
,
model
):
...
@@ -515,7 +516,7 @@ class ModelView(BaseModelView):
...
@@ -515,7 +516,7 @@ class ModelView(BaseModelView):
self
.
session
.
commit
()
self
.
session
.
commit
()
return
True
return
True
except
Exception
,
ex
:
except
Exception
,
ex
:
flash
(
'Failed to update model. '
+
str
(
ex
),
'error'
)
flash
(
gettext
(
'Failed to update model.
%(error)
s'
,
error
=
str
(
ex
)
),
'error'
)
return
False
return
False
def
delete_model
(
self
,
model
):
def
delete_model
(
self
,
model
):
...
@@ -530,5 +531,5 @@ class ModelView(BaseModelView):
...
@@ -530,5 +531,5 @@ class ModelView(BaseModelView):
self
.
session
.
commit
()
self
.
session
.
commit
()
return
True
return
True
except
Exception
,
ex
:
except
Exception
,
ex
:
flash
(
'Failed to delete model. '
+
str
(
ex
),
'error'
)
flash
(
gettext
(
'Failed to delete model.
%(error)
s'
,
error
=
str
(
ex
)
),
'error'
)
return
False
return
False
flask_adminex/form.py
View file @
ee46f523
...
@@ -4,6 +4,8 @@ import datetime
...
@@ -4,6 +4,8 @@ import datetime
from
flask.ext
import
wtf
from
flask.ext
import
wtf
from
wtforms
import
fields
,
widgets
from
wtforms
import
fields
,
widgets
from
flask.ext.adminex.babel
import
gettext
class
BaseForm
(
wtf
.
Form
):
class
BaseForm
(
wtf
.
Form
):
"""
"""
...
@@ -76,7 +78,7 @@ class TimeField(fields.Field):
...
@@ -76,7 +78,7 @@ class TimeField(fields.Field):
except
ValueError
:
except
ValueError
:
pass
pass
raise
ValueError
(
'Invalid time format'
)
raise
ValueError
(
gettext
(
'Invalid time format'
)
)
class
ChosenSelectWidget
(
widgets
.
Select
):
class
ChosenSelectWidget
(
widgets
.
Select
):
...
...
flask_adminex/model/base.py
View file @
ee46f523
from
flask
import
request
,
url_for
,
redirect
,
flash
from
flask
import
request
,
url_for
,
redirect
,
flash
from
flask.ext.babel
import
gettext
from
flask.ext.adminex.base
import
BaseView
,
expose
from
flask.ext.adminex.base
import
BaseView
,
expose
from
flask.ext.adminex.model
import
filters
from
flask.ext.adminex.model
import
filters
...
@@ -737,7 +739,7 @@ class BaseModelView(BaseView):
...
@@ -737,7 +739,7 @@ class BaseModelView(BaseView):
if
form
.
validate_on_submit
():
if
form
.
validate_on_submit
():
if
self
.
create_model
(
form
):
if
self
.
create_model
(
form
):
if
'_add_another'
in
request
.
form
:
if
'_add_another'
in
request
.
form
:
flash
(
'Model was successfully created.'
)
flash
(
gettext
(
'Model was successfully created.'
)
)
return
redirect
(
url_for
(
'.create_view'
,
url
=
return_url
))
return
redirect
(
url_for
(
'.create_view'
,
url
=
return_url
))
else
:
else
:
return
redirect
(
return_url
)
return
redirect
(
return_url
)
...
...
flask_adminex/model/filters.py
View file @
ee46f523
from
flask.ext.babel
import
lazy_gettext
class
BaseFilter
(
object
):
class
BaseFilter
(
object
):
"""
"""
Base filter class.
Base filter class.
...
@@ -76,7 +79,8 @@ class BaseBooleanFilter(BaseFilter):
...
@@ -76,7 +79,8 @@ class BaseBooleanFilter(BaseFilter):
"""
"""
def
__init__
(
self
,
name
,
data_type
=
None
):
def
__init__
(
self
,
name
,
data_type
=
None
):
super
(
BaseBooleanFilter
,
self
)
.
__init__
(
name
,
super
(
BaseBooleanFilter
,
self
)
.
__init__
(
name
,
((
'1'
,
'Yes'
),
(
'0'
,
'No'
)),
((
'1'
,
lazy_gettext
(
'Yes'
)),
(
'0'
,
lazy_gettext
(
'No'
))),
data_type
)
data_type
)
def
validate
(
self
,
value
):
def
validate
(
self
,
value
):
...
...
flask_adminex/templates/admin/file/form.html
View file @
ee46f523
{% extends 'admin/master.html' %}
{% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib %}
{% import 'admin/lib.html' as lib
with context
%}
{% block body %}
{% block body %}
{{ lib.render_form(form, dir_url) }}
{{ lib.render_form(form, dir_url) }}
...
...
flask_adminex/templates/admin/file/list.html
View file @
ee46f523
{% extends 'admin/master.html' %}
{% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib %}
{% import 'admin/lib.html' as lib
with context
%}
{% block body %}
{% block body %}
<ul
class=
"breadcrumb"
>
<ul
class=
"breadcrumb"
>
<li>
<li>
<a
href=
"{{ get_dir_url('.index', path=None) }}"
>
Root
</a>
<a
href=
"{{ get_dir_url('.index', path=None) }}"
>
{{ _gettext('Root') }}
</a>
</li>
</li>
{% for name, path in breadcrumbs[:-1] %}
{% for name, path in breadcrumbs[:-1] %}
<li>
<li>
...
@@ -39,7 +39,7 @@
...
@@ -39,7 +39,7 @@
{% if name != '..' and admin_view.can_delete_dirs %}
{% if name != '..' and admin_view.can_delete_dirs %}
<form
class=
"icon"
method=
"POST"
action=
"{{ url_for('.delete') }}"
>
<form
class=
"icon"
method=
"POST"
action=
"{{ url_for('.delete') }}"
>
<input
type=
"hidden"
name=
"path"
value=
"{{ path }}"
></input>
<input
type=
"hidden"
name=
"path"
value=
"{{ path }}"
></input>
<button
onclick=
"return confirm('
Are you sure you want to delete \'{{ name }}\' recursively?
')"
>
<button
onclick=
"return confirm('
{{ _gettext('Are you sure you want to delete \\\'%(name)s\\\' recursively?', name=name) }}
')"
>
<i
class=
"icon-remove"
></i>
<i
class=
"icon-remove"
></i>
</button>
</button>
</form>
</form>
...
@@ -47,7 +47,7 @@
...
@@ -47,7 +47,7 @@
{% else %}
{% else %}
<form
class=
"icon"
method=
"POST"
action=
"{{ url_for('.delete') }}"
>
<form
class=
"icon"
method=
"POST"
action=
"{{ url_for('.delete') }}"
>
<input
type=
"hidden"
name=
"path"
value=
"{{ path }}"
></input>
<input
type=
"hidden"
name=
"path"
value=
"{{ path }}"
></input>
<button
onclick=
"return confirm('
Are you sure you want to delete \'{{ name }}\'?
')"
>
<button
onclick=
"return confirm('
{{ _gettext('Are you sure you want to delete \\\'%(name)s\\\'?', name=name) }}
')"
>
<i
class=
"icon-remove"
></i>
<i
class=
"icon-remove"
></i>
</button>
</button>
</form>
</form>
...
@@ -72,9 +72,9 @@
...
@@ -72,9 +72,9 @@
{% endfor %}
{% endfor %}
</table>
</table>
{% if admin_view.can_upload %}
{% if admin_view.can_upload %}
<a
class=
"btn btn-primary btn-large"
href=
"{{ get_dir_url('.upload', path=dir_path) }}"
>
Upload File
</a>
<a
class=
"btn btn-primary btn-large"
href=
"{{ get_dir_url('.upload', path=dir_path) }}"
>
{{ _gettext('Upload File') }}
</a>
{% endif %}
{% endif %}
{% if admin_view.can_mkdir %}
{% if admin_view.can_mkdir %}
<a
class=
"btn btn-primary btn-large"
href=
"{{ get_dir_url('.mkdir', path=dir_path) }}"
>
Create Directory
</a>
<a
class=
"btn btn-primary btn-large"
href=
"{{ get_dir_url('.mkdir', path=dir_path) }}"
>
{{ _gettext('Create Directory') }}
</a>
{% endif %}
{% endif %}
{% endblock %}
{% endblock %}
flask_adminex/templates/admin/file/rename.html
View file @
ee46f523
{% extends 'admin/master.html' %}
{% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib %}
{% import 'admin/lib.html' as lib
with context
%}
{% block body %}
{% block body %}
<h3>
Please provide new name for
<i>
{{ name }}
</i>
</h3>
<h3>
{{ _gettext('Please provide new name for %(name)s', name=name) }}
</h3>
{{ lib.render_form(form, dir_url) }}
{{ lib.render_form(form, dir_url) }}
{% endblock %}
{% endblock %}
\ No newline at end of file
flask_adminex/templates/admin/lib.html
View file @
ee46f523
...
@@ -107,7 +107,7 @@
...
@@ -107,7 +107,7 @@
{{ extra }}
{{ extra }}
{% endif %}
{% endif %}
{% if cancel_url %}
{% if cancel_url %}
<a
href=
"{{ cancel_url }}"
class=
"btn btn-large"
>
Cancel
</a>
<a
href=
"{{ cancel_url }}"
class=
"btn btn-large"
>
{{ _gettext('Cancel') }}
</a>
{% endif %}
{% endif %}
</div>
</div>
</div>
</div>
...
...
flask_adminex/templates/admin/model/create.html
View file @
ee46f523
{% extends 'admin/master.html' %}
{% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib %}
{% import 'admin/lib.html' as lib
with context
%}
{% block head %}
{% block head %}
<link
href=
"{{ url_for('admin.static', filename='chosen/chosen.css') }}"
rel=
"stylesheet"
>
<link
href=
"{{ url_for('admin.static', filename='chosen/chosen.css') }}"
rel=
"stylesheet"
>
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
{% block body %}
{% block body %}
{% macro extra() %}
{% macro extra() %}
<input
name=
"_add_another"
type=
"submit"
class=
"btn btn-primary btn-large"
value=
"
Save and Add
"
/>
<input
name=
"_add_another"
type=
"submit"
class=
"btn btn-primary btn-large"
value=
"
{{ _gettext('Save and Add') }}
"
/>
{% endmacro %}
{% endmacro %}
<ul
class=
"nav nav-tabs"
>
<ul
class=
"nav nav-tabs"
>
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
<a
href=
"{{ return_url }}"
>
List
</a>
<a
href=
"{{ return_url }}"
>
List
</a>
</li>
</li>
<li
class=
"active"
>
<li
class=
"active"
>
<a
href=
"#"
>
Create
</a>
<a
href=
"#"
>
{{ _gettext('Create') }}
</a>
</li>
</li>
</ul>
</ul>
{{ lib.render_form(form, return_url, extra()) }}
{{ lib.render_form(form, return_url, extra()) }}
...
...
flask_adminex/templates/admin/model/edit.html
View file @
ee46f523
{% extends 'admin/master.html' %}
{% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib %}
{% import 'admin/lib.html' as lib
with context
%}
{% block head %}
{% block head %}
<link
href=
"{{ url_for('admin.static', filename='chosen/chosen.css') }}"
rel=
"stylesheet"
>
<link
href=
"{{ url_for('admin.static', filename='chosen/chosen.css') }}"
rel=
"stylesheet"
>
...
...
flask_adminex/templates/admin/model/list.html
View file @
ee46f523
{% extends 'admin/master.html' %}
{% extends 'admin/master.html' %}
{% import 'admin/lib.html' as lib %}
{% import 'admin/lib.html' as lib
with context
%}
{% block head %}
{% block head %}
<link
href=
"{{ url_for('admin.static', filename='chosen/chosen.css') }}"
rel=
"stylesheet"
>
<link
href=
"{{ url_for('admin.static', filename='chosen/chosen.css') }}"
rel=
"stylesheet"
>
...
@@ -9,18 +9,18 @@
...
@@ -9,18 +9,18 @@
{% block body %}
{% block body %}
<ul
class=
"nav nav-tabs"
>
<ul
class=
"nav nav-tabs"
>
<li
class=
"active"
>
<li
class=
"active"
>
<a
href=
"#"
>
List
({{ count }})
</a>
<a
href=
"#"
>
{{ _gettext('List') }}
({{ count }})
</a>
</li>
</li>
{% if admin_view.can_create %}
{% if admin_view.can_create %}
<li>
<li>
<a
href=
"{{ url_for('.create_view', url=return_url) }}"
>
Create
</a>
<a
href=
"{{ url_for('.create_view', url=return_url) }}"
>
{{ _gettext('Create') }}
</a>
</li>
</li>
{% endif %}
{% endif %}
{% if filter_groups %}
{% if filter_groups %}
<li
class=
"dropdown"
>
<li
class=
"dropdown"
>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
<a
class=
"dropdown-toggle"
data-toggle=
"dropdown"
href=
"#"
>
Add Filter
<b
class=
"caret"
></b>
{{ _gettext('Add Filter') }}
<b
class=
"caret"
></b>
</a>
</a>
<ul
class=
"dropdown-menu field-filters"
>
<ul
class=
"dropdown-menu field-filters"
>
{% for k in filter_groups %}
{% for k in filter_groups %}
...
@@ -41,7 +41,7 @@
...
@@ -41,7 +41,7 @@
{% if sort_desc %}
{% if sort_desc %}
<input
type=
"hidden"
name=
"desc"
value=
"{{ sort_desc }}"
></input>
<input
type=
"hidden"
name=
"desc"
value=
"{{ sort_desc }}"
></input>
{% endif %}
{% endif %}
<input
type=
"text"
name=
"search"
value=
"{{ search or '' }}"
class=
"search-query span2"
placeholder=
"
Search
"
></input>
<input
type=
"text"
name=
"search"
value=
"{{ search or '' }}"
class=
"search-query span2"
placeholder=
"
{{ _gettext('Search') }}
"
></input>
{% if search %}
{% if search %}
<a
href=
"{{ clear_search_url }}"
class=
"clear"
>
<a
href=
"{{ clear_search_url }}"
class=
"clear"
>
<i
class=
"icon-remove"
></i>
<i
class=
"icon-remove"
></i>
...
@@ -54,9 +54,9 @@
...
@@ -54,9 +54,9 @@
{% if filter_groups %}
{% if filter_groups %}
<form
id=
"filter_form"
method=
"GET"
action=
"{{ return_url }}"
>
<form
id=
"filter_form"
method=
"GET"
action=
"{{ return_url }}"
>
<div
class=
"pull-right"
>
<div
class=
"pull-right"
>
<button
type=
"submit"
class=
"btn btn-primary"
style=
"display: none"
>
Apply
</button>
<button
type=
"submit"
class=
"btn btn-primary"
style=
"display: none"
>
{{ _gettext('Apply') }}
</button>
{% if active_filters %}
{% if active_filters %}
<a
href=
"{{ clear_search_url }}"
class=
"btn"
>
Reset Filters
</a>
<a
href=
"{{ clear_search_url }}"
class=
"btn"
>
{{ _gettext('Reset Filters') }}
</a>
{% endif %}
{% endif %}
</div>
</div>
...
@@ -64,7 +64,7 @@
...
@@ -64,7 +64,7 @@
{%- for i, flt in enumerate(active_filters) -%}
{%- for i, flt in enumerate(active_filters) -%}
<div
class=
"filter-row"
>
<div
class=
"filter-row"
>
{% set filter = admin_view._filters[flt[0]] %}
{% set filter = admin_view._filters[flt[0]] %}
<a
href=
"#"
class=
"btn remove-filter"
title=
"
Remove Filter
"
>
<a
href=
"#"
class=
"btn remove-filter"
title=
"
{{ _gettext('Remove Filter') }}
"
>
{{ filters[flt[0]] }}
{{ filters[flt[0]] }}
</a><select
class=
"filter-op"
data-role=
"chosen"
>
</a><select
class=
"filter-op"
data-role=
"chosen"
>
{% for op in admin_view._filter_dict[filter.name] %}
{% for op in admin_view._filter_dict[filter.name] %}
...
@@ -125,7 +125,7 @@
...
@@ -125,7 +125,7 @@
{%- endif -%}
{%- endif -%}
{%- if admin_view.can_delete -%}
{%- if admin_view.can_delete -%}
<form
class=
"icon"
method=
"POST"
action=
"{{ url_for('.delete_view', id=get_pk_value(row), url=return_url) }}"
>
<form
class=
"icon"
method=
"POST"
action=
"{{ url_for('.delete_view', id=get_pk_value(row), url=return_url) }}"
>
<button
onclick=
"return confirm('
You sure you want to delete this item?')
"
>
<button
onclick=
"return confirm('
{{ _gettext('You sure you want to delete this item?') }}');
"
>
<i
class=
"icon-remove"
></i>
<i
class=
"icon-remove"
></i>
</button>
</button>
</form>
</form>
...
...
flask_adminex/tests/test_base.py
View file @
ee46f523
...
@@ -182,7 +182,6 @@ def test_submenu():
...
@@ -182,7 +182,6 @@ def test_submenu():
eq_
(
admin
.
_menu
[
1
]
.
is_accessible
(),
False
)
eq_
(
admin
.
_menu
[
1
]
.
is_accessible
(),
False
)
eq_
(
len
(
admin
.
_menu
[
1
]
.
get_children
()),
1
)
eq_
(
len
(
admin
.
_menu
[
1
]
.
get_children
()),
1
)
ok_
(
repr
(
admin
.
_menu
[
1
])
.
startswith
(
'MenuItem '
))
def
test_delayed_init
():
def
test_delayed_init
():
...
...
flask_adminex/tests/test_sqlamodel.py
View file @
ee46f523
...
@@ -217,8 +217,8 @@ def test_column_filters():
...
@@ -217,8 +217,8 @@ def test_column_filters():
eq_
(
view
.
_filter_dict
,
{
'Test1'
:
[(
0
,
'equals'
),
eq_
(
view
.
_filter_dict
,
{
'Test1'
:
[(
0
,
'equals'
),
(
1
,
'not equal'
),
(
1
,
'not equal'
),
(
2
,
'
like
'
),
(
2
,
'
contains
'
),
(
3
,
'not
like
'
)]})
(
3
,
'not
contains
'
)]})
db
.
session
.
add
(
Model1
(
'model1'
))
db
.
session
.
add
(
Model1
(
'model1'
))
db
.
session
.
add
(
Model1
(
'model2'
))
db
.
session
.
add
(
Model1
(
'model2'
))
...
...
setup.py
View file @
ee46f523
...
@@ -18,7 +18,7 @@ setup(
...
@@ -18,7 +18,7 @@ setup(
platforms
=
'any'
,
platforms
=
'any'
,
install_requires
=
[
install_requires
=
[
'Flask>=0.7'
,
'Flask>=0.7'
,
'Flask-WTF>=0.6'
,
'Flask-WTF>=0.6'
],
],
tests_require
=
[
tests_require
=
[
'nose>=1.0'
'nose>=1.0'
...
...
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