Commit 5e1d3b27 authored by Paul Brown's avatar Paul Brown

allow easier overriding of editable list view

parent 96f46153
......@@ -399,17 +399,26 @@ class ModelView(BaseModelView):
return form_class
def scaffold_list_form(self):
def scaffold_list_form(self, CustomFieldList, validators=None):
"""
Create form for the `index_view` using only the columns from
`self.column_editable_list`.
:param validators:
`form_args` dict with only validators
{'name': {'validators': [required()]}}
:param CustomFieldList:
A WTForm FieldList class. By default, `ListEditableFieldList`.
"""
form_class = get_form(self.model,
self.model_form_converter(self),
base_class=self.form_base_class,
only=self.column_editable_list)
only=self.column_editable_list,
field_args=validators)
return wrap_fields_in_fieldlist(self.form_base_class, form_class)
return wrap_fields_in_fieldlist(self.form_base_class,
form_class,
CustomFieldList)
# AJAX foreignkey support
def _create_ajax_loader(self, name, opts):
......
......@@ -238,16 +238,25 @@ class ModelView(BaseModelView):
return form_class
def scaffold_list_form(self):
def scaffold_list_form(self, CustomFieldList, validators=None):
"""
Create form for the `index_view` using only the columns from
`self.column_editable_list`.
:param validators:
`form_args` dict with only validators
{'name': {'validators': [required()]}}
:param CustomFieldList:
A WTForm FieldList class. By default, `ListEditableFieldList`.
"""
form_class = get_form(self.model, self.model_form_converter(self),
base_class=self.form_base_class,
only=self.column_editable_list)
only=self.column_editable_list,
field_args=validators)
return wrap_fields_in_fieldlist(self.form_base_class, form_class)
return wrap_fields_in_fieldlist(self.form_base_class,
form_class,
CustomFieldList)
def scaffold_inline_form_models(self, form_class):
converter = self.model_form_converter(self)
......
......@@ -612,17 +612,26 @@ class ModelView(BaseModelView):
return form_class
def scaffold_list_form(self):
def scaffold_list_form(self, CustomFieldList, validators=None):
"""
Create form for the `index_view` using only the columns from
`self.column_editable_list`.
:param validators:
`form_args` dict with only validators
{'name': {'validators': [required()]}}
:param CustomFieldList:
A WTForm FieldList class. By default, `ListEditableFieldList`.
"""
converter = self.model_form_converter(self.session, self)
form_class = form.get_form(self.model, converter,
base_class=self.form_base_class,
only=self.column_editable_list)
only=self.column_editable_list,
field_args=validators)
return wrap_fields_in_fieldlist(self.form_base_class, form_class)
return wrap_fields_in_fieldlist(self.form_base_class,
form_class,
CustomFieldList)
def scaffold_inline_form_models(self, form_class):
"""
......
......@@ -20,6 +20,7 @@ from flask.ext.admin._backwards import ObsoleteAttr
from flask.ext.admin._compat import iteritems, OrderedDict, as_unicode
from .helpers import prettify_name, get_mdict_item_or_list
from .ajax import AjaxModelLoader
from .fields import ListEditableFieldList
# Used to generate filter query string name
......@@ -596,7 +597,7 @@ class BaseModelView(BaseView, ActionsMixin):
# List View In-Line Editing
if self.column_editable_list:
self._list_form_class = self.scaffold_list_form()
self._list_form_class = self.get_list_form()
else:
self.column_editable_list = {}
......@@ -853,10 +854,18 @@ class BaseModelView(BaseView, ActionsMixin):
"""
raise NotImplementedError('Please implement scaffold_form method')
def scaffold_list_form(self):
def scaffold_list_form(self, CustomFieldList, validators=None):
"""
Create form for the `index_view` using only the columns from
`self.column_editable_list`. Must be implemented in the child class.
`self.column_editable_list`.
:param validators:
`form_args` dict with only validators
{'name': {'validators': [required()]}}
:param CustomFieldList:
A WTForm FieldList class. By default, `ListEditableFieldList`.
Must be implemented in the child class.
"""
raise NotImplementedError('Please implement scaffold_list_form method')
......@@ -874,6 +883,45 @@ class BaseModelView(BaseView, ActionsMixin):
return self.scaffold_form()
def get_list_form(self):
"""
Get form class for the editable list view.
Uses only validators from `form_args` to build the form class.
Allows overriding the editable list view field/widget. For example::
from flask.ext.admin.model.fields import ListEditableFieldList
from flask.ext.admin.model.widgets import XEditableWidget
class CustomWidget(XEditableWidget):
def get_kwargs(self, subfield, kwargs):
if subfield.type == 'TextAreaField':
kwargs['data-type'] = 'textarea'
kwargs['data-rows'] = '20'
# elif: kwargs for other fields
return kwargs
class CustomFieldList(ListEditableFieldList):
widget = CustomWidget()
class MyModelView(BaseModelView):
def get_list_form(self):
return self.scaffold_list_form(CustomFieldList)
"""
if self.form_args:
# get only validators, other form_args can break FieldList wrapper
validators = dict(
(key, {'validators': value["validators"]})
for key, value in iteritems(self.form_args)
if value.get("validators")
)
else:
validators = None
return self.scaffold_list_form(ListEditableFieldList, validators)
def get_create_form(self):
"""
Create form class for model creation view.
......
......@@ -3,7 +3,6 @@ import inspect
from flask.ext.admin.form import BaseForm, rules
from flask.ext.admin._compat import iteritems
from .fields import ListEditableFieldList
from wtforms.fields.core import UnboundField
......@@ -14,7 +13,7 @@ def converts(*args):
return _inner
def wrap_fields_in_fieldlist(form_base_class, form_class):
def wrap_fields_in_fieldlist(form_base_class, form_class, CustomFieldList):
"""
Create a form class with all the fields wrapped in a FieldList.
......@@ -22,6 +21,14 @@ def wrap_fields_in_fieldlist(form_base_class, form_class):
in this format: ('<field_name>-<primary_key>', '<value>')
Used in the editable list view.
:param form_base_class:
WTForms form class, by default `form_base_class` from base.
:param form_class:
WTForms form class generated by `form.get_form`.
:param CustomFieldList:
WTForms FieldList class.
By default, `CustomFieldList` is `ListEditableFieldList`.
"""
class FieldListForm(form_base_class):
pass
......@@ -30,7 +37,7 @@ def wrap_fields_in_fieldlist(form_base_class, form_class):
for name, obj in iteritems(form_class.__dict__):
if isinstance(obj, UnboundField):
# wrap field in a WTForms FieldList
setattr(FieldListForm, name, ListEditableFieldList(obj))
setattr(FieldListForm, name, CustomFieldList(obj))
return FieldListForm
......
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