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
a260ad5f
Commit
a260ad5f
authored
Aug 26, 2012
by
Serge S. Koval
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Updated documentation
parent
2845e4b2
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
214 additions
and
118 deletions
+214
-118
actions.py
flask_admin/actions.py
+5
-5
base.py
flask_admin/base.py
+29
-18
fileadmin.py
flask_admin/contrib/fileadmin.py
+25
-20
filters.py
flask_admin/contrib/peeweemodel/filters.py
+4
-4
form.py
flask_admin/contrib/peeweemodel/form.py
+0
-1
fields.py
flask_admin/contrib/sqlamodel/fields.py
+17
-0
filters.py
flask_admin/contrib/sqlamodel/filters.py
+4
-4
form.py
flask_admin/contrib/sqlamodel/form.py
+40
-0
tools.py
flask_admin/contrib/sqlamodel/tools.py
+3
-0
view.py
flask_admin/contrib/sqlamodel/view.py
+25
-19
form.py
flask_admin/form.py
+13
-4
base.py
flask_admin/model/base.py
+30
-30
fields.py
flask_admin/model/fields.py
+6
-0
filters.py
flask_admin/model/filters.py
+7
-7
tools.py
flask_admin/tools.py
+6
-6
No files found.
flask_admin/actions.py
View file @
a260ad5f
...
...
@@ -6,11 +6,11 @@ def action(name, text, confirmation=None):
Use this decorator to expose actions that span more than one
entity (model, file, etc)
`name`
:param name:
Action name
`text`
:param text:
Action text.
`confirmation`
:param confirmation:
Confirmation text. If not provided, action will be executed
unconditionally.
"""
...
...
@@ -64,7 +64,7 @@ class ActionsMixin(object):
"""
Verify if action with `name` is allowed.
`name`
:param name:
Action name
"""
return
True
...
...
@@ -93,7 +93,7 @@ class ActionsMixin(object):
"""
Handle action request.
`return_view`
:param return_view:
Name of the view to return to after the request.
If not provided, will return user to the index view.
"""
...
...
flask_admin/base.py
View file @
a260ad5f
...
...
@@ -10,9 +10,9 @@ def expose(url='/', methods=('GET',)):
"""
Use this decorator to expose views in your view classes.
`url`
:param url:
Relative URL for the view
`methods`
:param methods:
Allowed HTTP methods. By default only GET is allowed.
"""
def
wrap
(
f
):
...
...
@@ -84,16 +84,16 @@ class BaseView(object):
"""
Constructor.
`name`
:param name:
Name of this view. If not provided, will be defaulted to the class name.
`category`
:param category:
View category. If not provided, will be shown as a top-level menu item. Otherwise, will
be in a submenu.
`endpoint`
:param endpoint:
Base endpoint name for the view. For example, if there's view method called "index" and
endpoint was set to "myadmin", you can use `url_for('myadmin.index')` to get URL to the
view method. By default, equals to the class name in lower case.
`url`
:param url:
Base URL. If provided, affects how URLs are generated. For example, if url parameter
equals to "test", resulting URL will look like "/admin/test/". If not provided, will
use endpoint as a base url. However, if URL starts with '/', absolute path is assumed
...
...
@@ -161,9 +161,9 @@ class BaseView(object):
"""
Render template
`template`
:param template:
Template path to render
`kwargs`
:param kwargs:
Template arguments
"""
# Store self as admin_view
...
...
@@ -180,7 +180,7 @@ class BaseView(object):
"""
Prettify class name by splitting name by capital characters. So, 'MySuperClass' will look like 'My Super Class'
`name`
:param name:
String to prettify
"""
return
sub
(
r'(?<=.)([A-Z])'
,
r' \1'
,
name
)
...
...
@@ -197,6 +197,17 @@ class BaseView(object):
return
True
def
_handle_view
(
self
,
name
,
**
kwargs
):
"""
This method will be executed before calling any view method.
By default, it will check if admin class is accessible and if it is not - will
throw HTTP 403 error.
:param name:
View function name
:param kwargs:
View function arguments
"""
if
not
self
.
is_accessible
():
return
abort
(
403
)
...
...
@@ -295,17 +306,17 @@ class Admin(object):
"""
Constructor.
`app`
:param app:
Flask application object
`name`
:param name:
Application name. Will be displayed in main menu and as a page title. If not provided, defaulted to "Admin"
`url`
:param url:
Base URL
`subdomain`
:param subdomain:
Subdomain to use
`index_view`
:param index_view:
Home page view to use. If not provided, will use `AdminIndexView`.
`translations_path`
:param translations_path:
Location of the translation message catalogs. By default will use translations
shipped with the Flask-Admin.
"""
...
...
@@ -345,7 +356,7 @@ class Admin(object):
"""
Add view to the collection.
`view`
:param view:
View to add.
"""
# Add to views
...
...
@@ -391,7 +402,7 @@ class Admin(object):
"""
Add view to the menu tree
`view`
:param view:
View to add
"""
if
view
.
category
:
...
...
@@ -410,7 +421,7 @@ class Admin(object):
"""
Register all views with Flask application.
`app`
:param app:
Flask application instance
"""
if
self
.
app
is
not
None
:
...
...
flask_admin/contrib/fileadmin.py
View file @
a260ad5f
...
...
@@ -61,9 +61,9 @@ class FileAdmin(BaseView, ActionsMixin):
Requires two parameters:
`path`
:param path:
Path to the directory which will be managed
`url`
:param url:
Base URL for the directory. Will be used to generate
static links to the files.
...
...
@@ -137,19 +137,19 @@ class FileAdmin(BaseView, ActionsMixin):
"""
Constructor.
`base_path`
:param base_path:
Base file storage location
`base_url`
:param base_url:
Base URL for the files
`name`
:param name:
Name of this view. If not provided, will be defaulted to the class name.
`category`
:param category:
View category
`endpoint`
:param endpoint:
Endpoint name for the view
`url`
:param url:
URL for view
`verify_path`
:param verify_path:
Verify if path exists. If set to `True` and path does not exist
will throw exception.
"""
...
...
@@ -177,7 +177,7 @@ class FileAdmin(BaseView, ActionsMixin):
Override to customize behavior.
`path`
:param path:
Relative path to the root
"""
return
True
...
...
@@ -202,7 +202,7 @@ class FileAdmin(BaseView, ActionsMixin):
Override to customize behavior.
`filename`
:param filename:
Source file name
"""
ext
=
op
.
splitext
(
filename
)[
1
]
.
lower
()
...
...
@@ -218,6 +218,11 @@ class FileAdmin(BaseView, ActionsMixin):
def
is_in_folder
(
self
,
base_path
,
directory
):
"""
Verify if `directory` is in `base_path` folder
:param base_path:
Base directory path
:param directory:
Directory path to check
"""
return
op
.
normpath
(
directory
)
.
startswith
(
base_path
)
...
...
@@ -225,9 +230,9 @@ class FileAdmin(BaseView, ActionsMixin):
"""
Save uploaded file to the disk
`path`
:param path:
Path to save to
`file_data`
:param file_data:
Werkzeug `FileStorage` object
"""
file_data
.
save
(
path
)
...
...
@@ -236,11 +241,11 @@ class FileAdmin(BaseView, ActionsMixin):
"""
Return prettified URL
`endpoint`
:param endpoint:
Endpoint name
`path`
:param path:
Directory path
`kwargs`
:param kwargs:
Additional arguments
"""
if
not
path
:
...
...
@@ -257,7 +262,7 @@ class FileAdmin(BaseView, ActionsMixin):
"""
Return static file url
`path`
:param path:
Static file path
"""
base_url
=
self
.
get_base_url
()
...
...
@@ -300,7 +305,7 @@ class FileAdmin(BaseView, ActionsMixin):
"""
Index view method
`path`
:param path:
Optional directory path. If not provided, will use base directory
"""
# Get path and verify if it is valid
...
...
@@ -350,7 +355,7 @@ class FileAdmin(BaseView, ActionsMixin):
"""
Upload view method
`path`
:param path:
Optional directory path. If not provided, will use base directory
"""
# Get path and verify if it is valid
...
...
@@ -383,7 +388,7 @@ class FileAdmin(BaseView, ActionsMixin):
"""
Directory creation view method
`path`
:param path:
Optional directory path. If not provided, will use base directory
"""
# Get path and verify if it is valid
...
...
flask_admin/contrib/peeweemodel/filters.py
View file @
a260ad5f
...
...
@@ -11,13 +11,13 @@ class BasePeeweeFilter(filters.BaseFilter):
"""
Constructor.
`column`
:param column:
Model field
`name`
:param name:
Display name
`options`
:param options:
Fixed set of options
`data_type`
:param data_type:
Client data type
"""
super
(
BasePeeweeFilter
,
self
)
.
__init__
(
name
,
options
,
data_type
)
...
...
flask_admin/contrib/peeweemodel/form.py
View file @
a260ad5f
...
...
@@ -20,7 +20,6 @@ class InlineModelFormList(fields.FieldList):
self
.
model
=
model
self
.
prop
=
prop
# TODO: Fix me
self
.
_pk
=
get_primary_key
(
model
)
super
(
InlineModelFormList
,
self
)
.
__init__
(
InlineModelFormField
(
form
,
self
.
_pk
),
**
kwargs
)
...
...
flask_admin/contrib/sqlamodel/fields.py
View file @
a260ad5f
...
...
@@ -181,9 +181,26 @@ class QuerySelectMultipleField(QuerySelectField):
class
InlineModelFormList
(
FieldList
):
"""
Customizied ``wtforms.fields.FieldList`` class which will work with SQLAlchemy
model instances.
"""
widget
=
InlineFormListWidget
()
def
__init__
(
self
,
form
,
session
,
model
,
prop
,
**
kwargs
):
"""
Default constructor.
:param form:
Form for the related model
:param session:
SQLAlchemy session
:param model:
Related model
:param prop:
Related property name
"""
self
.
form
=
form
self
.
session
=
session
self
.
model
=
model
...
...
flask_admin/contrib/sqlamodel/filters.py
View file @
a260ad5f
...
...
@@ -12,13 +12,13 @@ class BaseSQLAFilter(filters.BaseFilter):
"""
Constructor.
`column`
:param column:
Model field
`name`
:param name:
Display name
`options`
:param options:
Fixed set of options
`data_type`
:param data_type:
Client data type
"""
super
(
BaseSQLAFilter
,
self
)
.
__init__
(
name
,
options
,
data_type
)
...
...
flask_admin/contrib/sqlamodel/form.py
View file @
a260ad5f
...
...
@@ -239,6 +239,24 @@ def get_form(model, converter,
only
=
None
,
exclude
=
None
,
field_args
=
None
,
hidden_pk
=
False
):
"""
Generate form from the model.
:param model:
Model to generate form from
:param converter:
Converter class to use
:param base_class:
Base form class
:param only:
Include fields
:param exclude:
Exclude fields
:param field_args:
Dictionary with additional field arguments
:param hidden_pk:
Generate hidden field with model primary key or not
"""
# TODO: Support new 0.8 API
if
not
hasattr
(
model
,
'_sa_class_manager'
):
...
...
@@ -263,6 +281,28 @@ def get_form(model, converter,
def
contribute_inline
(
session
,
model
,
form_class
,
inline_models
):
"""
Generate form fields for inline forms and contribute them to
the `form_class`
:param session:
SQLAlchemy session
:param model:
Model class
:param form_class:
Form to add properties to
:param inline_models:
List of inline model definitions. Can be one of:
- ``tuple``, first value is related model instance,
second is dictionary with options
- ``InlineFormAdmin`` instance
- Model class
:return:
Form class
"""
# Get mapper
mapper
=
model
.
_sa_class_manager
.
mapper
...
...
flask_admin/contrib/sqlamodel/tools.py
View file @
a260ad5f
...
...
@@ -12,6 +12,9 @@ def parse_like_term(term):
def
get_primary_key
(
model
):
"""
Return primary key name from a model
:param model:
Model class
"""
props
=
model
.
_sa_class_manager
.
mapper
.
iterate_properties
...
...
flask_admin/contrib/sqlamodel/view.py
View file @
a260ad5f
...
...
@@ -137,17 +137,17 @@ class ModelView(BaseModelView):
"""
Constructor.
`model`
:param model:
Model class
`session`
:param session:
SQLALchemy session
`name`
:param name:
View name. If not set, will default to model name
`category`
:param category:
Category name
`endpoint`
:param endpoint:
Endpoint name. If not set, will default to model name
`url`
:param url:
Base URL. If not set, will default to '/admin/' + endpoint
"""
self
.
session
=
session
...
...
@@ -295,12 +295,16 @@ class ModelView(BaseModelView):
"""
Verify if column type is text-based.
Returns `True` for `String`, `Unicode`, `Text`, `UnicodeText`
:returns:
``True`` for ``String``, ``Unicode``, ``Text``, ``UnicodeText``
"""
return
(
name
==
'String'
or
name
==
'Unicode'
or
name
==
'Text'
or
name
==
'UnicodeText'
)
def
scaffold_filters
(
self
,
name
):
"""
Return list of enabled filters
"""
if
isinstance
(
name
,
basestring
):
attr
=
getattr
(
self
.
model
,
name
,
None
)
else
:
...
...
@@ -363,7 +367,7 @@ class ModelView(BaseModelView):
Verify that provided filter object is derived from the
SQLAlchemy-compatible filter class.
`filter`
:param filter:
Filter object to verify.
"""
return
isinstance
(
filter
,
filters
.
BaseSQLAFilter
)
...
...
@@ -409,17 +413,17 @@ class ModelView(BaseModelView):
"""
Return models from the database.
`page`
:param page:
Page number
`sort_column`
:param sort_column:
Sort column name
`sort_desc`
:param sort_desc:
Descending or ascending sort
`search`
:param search:
Search query
`execute`
:param execute:
Execute query immediately? Default is `True`
`filters`
:param filters:
List of filter tuples
"""
...
...
@@ -515,8 +519,8 @@ class ModelView(BaseModelView):
"""
Return one model by its id.
`id`
Model
:param id:
Model
id
"""
return
self
.
session
.
query
(
self
.
model
)
.
get
(
id
)
...
...
@@ -525,7 +529,7 @@ class ModelView(BaseModelView):
"""
Create model from form.
`form`
:param form:
Form instance
"""
try
:
...
...
@@ -542,8 +546,10 @@ class ModelView(BaseModelView):
"""
Update model from form.
`form`
:param form:
Form instance
:param model:
Model instance
"""
try
:
form
.
populate_obj
(
model
)
...
...
@@ -557,7 +563,7 @@ class ModelView(BaseModelView):
"""
Delete model.
`model`
:param model:
Model to delete
"""
try
:
...
...
flask_admin/form.py
View file @
a260ad5f
...
...
@@ -45,13 +45,13 @@ class TimeField(fields.Field):
"""
Constructor
`label`
:param label:
Label
`validators`
:param validators:
Field validators
`formats`
:param formats:
Supported time formats, as a enumerable.
`kwargs`
:param kwargs:
Any additional parameters
"""
super
(
TimeField
,
self
)
.
__init__
(
label
,
validators
,
**
kwargs
)
...
...
@@ -130,7 +130,16 @@ class DateTimePickerWidget(widgets.TextInput):
class
RenderTemplateWidget
(
object
):
"""
WTForms widget that renders Jinja2 template
"""
def
__init__
(
self
,
template
):
"""
Constructor
:param template:
Template path
"""
self
.
template
=
template
def
__call__
(
self
,
field
,
**
kwargs
):
...
...
flask_admin/model/base.py
View file @
a260ad5f
...
...
@@ -222,17 +222,17 @@ class BaseModelView(BaseView, ActionsMixin):
"""
Constructor.
`model`
:param model:
Model class
`name`
:param name:
View name. If not provided, will use model class name
`category`
:param category:
View category
`endpoint`
:param endpoint:
Base endpoint. If not provided, will use model name + 'view'.
For example if model name was 'User', endpoint will be
'userview'
`url`
:param url:
Base URL. If not provided, will use endpoint as a URL.
"""
...
...
@@ -318,7 +318,7 @@ class BaseModelView(BaseView, ActionsMixin):
"""
Return human-readable column name.
`field`
:param field:
Model field name.
"""
if
self
.
rename_columns
and
field
in
self
.
rename_columns
:
...
...
@@ -381,7 +381,7 @@ class BaseModelView(BaseView, ActionsMixin):
"""
Generate filter object for the given name
`name`
:param name:
Name of the field
"""
return
None
...
...
@@ -393,7 +393,7 @@ class BaseModelView(BaseView, ActionsMixin):
Override in model backend implementation to verify if
provided filter type is allowed.
`filter`
:param filter:
Filter object to verify.
"""
return
isinstance
(
filter
,
filters
.
BaseFilter
)
...
...
@@ -480,7 +480,7 @@ class BaseModelView(BaseView, ActionsMixin):
"""
Verify if column is sortable.
`name`
:param name:
Column name.
"""
return
name
in
self
.
_sortable_columns
...
...
@@ -502,15 +502,15 @@ class BaseModelView(BaseView, ActionsMixin):
Must be implemented in child class.
`page`
:param page:
Page number, 0 based. Can be set to None if it is first page.
`sort_field`
:param sort_field:
Sort column name or None.
`sort_desc`
:param sort_desc:
If set to True, sorting is in descending order.
`search`
:param search:
Search query
`filters`
:param filters:
List of filter tuples. First value in a tuple is a search
index, second value is a search value.
"""
...
...
@@ -522,7 +522,7 @@ class BaseModelView(BaseView, ActionsMixin):
Must be implemented in the child class.
`id`
:param id:
Model id
"""
raise
NotImplemented
(
'Please implement get_one method'
)
...
...
@@ -536,7 +536,7 @@ class BaseModelView(BaseView, ActionsMixin):
Must be implemented in the child class.
`form`
:param form:
Form instance
"""
raise
NotImplemented
()
...
...
@@ -549,9 +549,9 @@ class BaseModelView(BaseView, ActionsMixin):
Must be implemented in the child class.
`form`
:param form:
Form instance
`model`
:param model:
Model instance
"""
raise
NotImplemented
()
...
...
@@ -564,7 +564,7 @@ class BaseModelView(BaseView, ActionsMixin):
Must be implemented in the child class.
`model`
:param model:
Model instance
"""
raise
NotImplemented
()
...
...
@@ -576,7 +576,7 @@ class BaseModelView(BaseView, ActionsMixin):
For example, 'hello_world' will be converted to 'Hello World'
`name`
:param name:
Name to prettify
"""
return
name
.
replace
(
'_'
,
' '
)
.
title
()
...
...
@@ -627,17 +627,17 @@ class BaseModelView(BaseView, ActionsMixin):
Generate page URL with current page, sort column and
other parameters.
`view`
:param view:
View name
`page`
:param page:
Page number
`sort`
:param sort:
Sort column index
`sort_desc`
:param sort_desc:
Use descending sorting order
`search`
:param search:
Search query
`filters`
:param filters:
List of active filters
"""
if
not
search
:
...
...
@@ -669,10 +669,10 @@ class BaseModelView(BaseView, ActionsMixin):
"""
Returns value to be displayed in list view
`model`
Model instance
`name`
Field name
:param model:
Model instance
:param name:
Field name
"""
if
name
in
self
.
list_formatters
:
return
self
.
list_formatters
[
name
](
model
,
name
)
...
...
flask_admin/model/fields.py
View file @
a260ad5f
...
...
@@ -2,6 +2,12 @@ from wtforms.fields import FormField
class
InlineModelFormField
(
FormField
):
"""
Customized ``FormField``.
Excludes model primary key from the `populate_obj` and
handles `should_delete` flag.
"""
def
__init__
(
self
,
form
,
pk
,
**
kwargs
):
super
(
InlineModelFormField
,
self
)
.
__init__
(
form
,
**
kwargs
)
...
...
flask_admin/model/filters.py
View file @
a260ad5f
...
...
@@ -9,11 +9,11 @@ class BaseFilter(object):
"""
Constructor.
`name`
:param name:
Displayed name
`options`
:param options:
List of fixed options. If provided, will use drop down instead of textbox.
`data_type`
:param data_type:
Client-side widget type to use.
"""
self
.
name
=
name
...
...
@@ -26,7 +26,7 @@ class BaseFilter(object):
Override to customize behavior.
`view`
:param view:
Associated administrative view class.
"""
return
self
.
options
...
...
@@ -37,7 +37,7 @@ class BaseFilter(object):
If value is valid, returns `True` and `False` otherwise.
`value`
:param value:
Value to validate
"""
return
True
...
...
@@ -46,7 +46,7 @@ class BaseFilter(object):
"""
Parse value into python format.
`value`
:param value:
Value to parse
"""
return
value
...
...
@@ -55,7 +55,7 @@ class BaseFilter(object):
"""
Apply search criteria to the query and return new query.
`query`
:param query:
Query
"""
raise
NotImplemented
()
...
...
flask_admin/tools.py
View file @
a260ad5f
...
...
@@ -6,9 +6,9 @@ def import_module(name, required=True):
"""
Import module by name
`name`
:param name:
Module name
`required`
:param required:
If set to `True` and module was not found - will throw exception.
If set to `False` and module was not found - will return None.
Default is `True`.
...
...
@@ -26,7 +26,7 @@ def import_attribute(name):
"""
Import attribute using string reference.
`name`
:param name:
String reference.
Throws ImportError or AttributeError if module or attribute do not exist.
...
...
@@ -47,7 +47,7 @@ def module_not_found(additional_depth=0):
Checks if ImportError was raised because module does not exist or
something inside it raised ImportError
`additional_depth`
:param additional_depth:
supply int of depth of your call if you're not doing
import on the same level of code - f.e., if you call function, which is
doing import, you should pass 1 for single additional level of depth
...
...
@@ -62,9 +62,9 @@ def rec_getattr(obj, attr, default=None):
"""
Recursive getattr.
`attr`
:param attr:
Dot delimited attribute name
`default`
:param default:
Default value
Example::
...
...
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