Commit 76558ff7 authored by Serge S. Koval's avatar Serge S. Koval

Merge branch 'master' of https://github.com/mrjoes/flask-admin

parents a1526ce9 8dfaff16
...@@ -12,3 +12,4 @@ dist/* ...@@ -12,3 +12,4 @@ dist/*
make.bat make.bat
venv venv
*.sqlite *.sqlite
*.sublime-*
from functools import wraps from functools import wraps
from re import sub from re import sub
from flask import Blueprint, render_template, url_for, abort from flask import Blueprint, render_template, url_for, abort, g
from flask.ext.admin import babel from flask.ext.admin import babel
...@@ -86,6 +86,37 @@ class BaseView(object): ...@@ -86,6 +86,37 @@ class BaseView(object):
""" """
__metaclass__ = AdminViewMeta __metaclass__ = AdminViewMeta
@property
def _template_args(self):
"""
Extra template arguments.
If you need to pass some extra parameters to the template,
you can override particular view function, contribute
arguments you want to pass to the template and call parent view.
These arguments are local for this request and will be discarded
in next request.
Any value passed through ``_template_args`` will override whatever
parent view function passed to the template.
For example::
class MyAdmin(ModelView):
@expose('/')
def index(self):
self._template_args['name'] = 'foobar'
self._template_args['code'] = '12345'
super(MyAdmin, self).index()
"""
args = getattr(g, '_admin_template_args', None)
if args is None:
args = g._admin_template_args = dict()
return args
def __init__(self, name=None, category=None, endpoint=None, url=None, static_folder=None): def __init__(self, name=None, category=None, endpoint=None, url=None, static_folder=None):
""" """
Constructor. Constructor.
...@@ -180,6 +211,9 @@ class BaseView(object): ...@@ -180,6 +211,9 @@ class BaseView(object):
kwargs['_gettext'] = babel.gettext kwargs['_gettext'] = babel.gettext
kwargs['_ngettext'] = babel.ngettext kwargs['_ngettext'] = babel.ngettext
# Contribute extra arguments
kwargs.update(self._template_args)
return render_template(template, **kwargs) return render_template(template, **kwargs)
def _prettify_name(self, name): def _prettify_name(self, name):
......
...@@ -246,7 +246,8 @@ def get_form(model, converter, ...@@ -246,7 +246,8 @@ def get_form(model, converter,
base_class=form.BaseForm, base_class=form.BaseForm,
only=None, exclude=None, only=None, exclude=None,
field_args=None, field_args=None,
hidden_pk=False): hidden_pk=False,
ignore_hidden=True):
""" """
Generate form from the model. Generate form from the model.
...@@ -264,6 +265,8 @@ def get_form(model, converter, ...@@ -264,6 +265,8 @@ def get_form(model, converter,
Dictionary with additional field arguments Dictionary with additional field arguments
:param hidden_pk: :param hidden_pk:
Generate hidden field with model primary key or not Generate hidden field with model primary key or not
:param ignore_hidden:
If set to True (default), will ignore properties that start with underscore
""" """
# TODO: Support new 0.8 API # TODO: Support new 0.8 API
...@@ -274,15 +277,34 @@ def get_form(model, converter, ...@@ -274,15 +277,34 @@ def get_form(model, converter,
field_args = field_args or {} field_args = field_args or {}
properties = ((p.key, p) for p in mapper.iterate_properties) properties = ((p.key, p) for p in mapper.iterate_properties)
if only: if only:
props = dict(properties)
def find(name):
# Try to look it up in properties lsit first
p = props.get(name)
if p is not None:
return p
# If it is hybrid property or alias, look it up in a model itself
p = getattr(model, name, None)
if p is not None and hasattr(p, 'property'):
return p.property
raise ValueError('Invalid model property name %s.%s' % (model, name))
# Filter properties while maintaining property order in 'only' list # Filter properties while maintaining property order in 'only' list
temp = dict(properties) properties = ((x, find(x)) for x in only)
properties = ((x, temp[x]) for x in only)
elif exclude: elif exclude:
properties = (x for x in properties if x[0] not in exclude) properties = (x for x in properties if x[0] not in exclude)
field_dict = {} field_dict = {}
for name, prop in properties: for name, prop in properties:
# Ignore protected properties
if ignore_hidden and name.startswith('_'):
continue
field = converter.convert(model, mapper, prop, field_args.get(name), hidden_pk) field = converter.convert(model, mapper, prop, field_args.get(name), hidden_pk)
if field is not None: if field is not None:
field_dict[name] = field field_dict[name] = field
......
...@@ -451,6 +451,12 @@ class ModelView(BaseModelView): ...@@ -451,6 +451,12 @@ class ModelView(BaseModelView):
return joined return joined
# Database-related API # Database-related API
def get_query(self):
"""
Return a query for the model type
"""
return self.session.query(self.model)
def get_list(self, page, sort_column, sort_desc, search, filters, execute=True): def get_list(self, page, sort_column, sort_desc, search, filters, execute=True):
""" """
Return models from the database. Return models from the database.
...@@ -472,7 +478,7 @@ class ModelView(BaseModelView): ...@@ -472,7 +478,7 @@ class ModelView(BaseModelView):
# Will contain names of joined tables to avoid duplicate joins # Will contain names of joined tables to avoid duplicate joins
joins = set() joins = set()
query = self.session.query(self.model) query = self.get_query()
# Apply search criteria # Apply search criteria
if self._search_supported and search: if self._search_supported and search:
...@@ -637,7 +643,7 @@ class ModelView(BaseModelView): ...@@ -637,7 +643,7 @@ class ModelView(BaseModelView):
try: try:
model_pk = getattr(self.model, self._primary_key) model_pk = getattr(self.model, self._primary_key)
query = self.session.query(self.model).filter(model_pk.in_(ids)) query = self.get_query().filter(model_pk.in_(ids))
if self.fast_mass_delete: if self.fast_mass_delete:
count = query.delete(synchronize_session=False) count = query.delete(synchronize_session=False)
......
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
</div> </div>
{% endblock %} {% endblock %}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
<script src="{{ url_for('admin.static', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script> <script src="{{ url_for('admin.static', filename='bootstrap/js/bootstrap.min.js') }}" type="text/javascript"></script>
<script src="{{ url_for('admin.static', filename='chosen/chosen.jquery.min.js') }}" type="text/javascript"></script> <script src="{{ url_for('admin.static', filename='chosen/chosen.jquery.min.js') }}" type="text/javascript"></script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment