2016-03-07 94 views
1

我有一个Flask应用程序,Flask-SQLAlchemyFlask-AdminFlask-Admin批量处理表格

我想执行一个批处理操作,但与窗体。例如,我想为归因的表单设置相同的文本值,但该值由用户输入。

我看到了documentation for batch actions,但它只有预定义数据的示例。

是否有可能,或者有一些解决方法呢?

回答

2

我实现这一目标的方法是在@action方法中执行内部POST。

class AddressView(AdminView): 

    # ... .... 

    @action('merge', 'Merge', 'Are you sure you want to merge selected addresses?') 
    def action_merge(self, ids): 

     if len(ids) < 2: 
      flash("Two or more addresses need to be selected before merging") 
      return 

     return_url = request.referrer 
     return redirect(url_for('mergeaddresses.index', return_url=return_url), code=307) 

然后定义两条路线,一个用于内部交,然后一个接收从接收用户的输入数据的形式(MergeAddressForm在下面的情况下)提交POST。

在下面的例子中,我碰巧使用Flask-Admin BaseView来处理路由。请注意,flask-admin列表视图中的原始已检查标识是如何检索的,然后作为已编码的逗号分隔列表隐藏字段存储在表单中,并且同样将return_url存储回flask-admin列表视图。

class MergeAddressesView(BaseView): 

    form_base_class = BaseForm 

    def __init__(self, name=None, category=None, 
       endpoint=None, url=None, 
       template='admin/index.html', 
       menu_class_name=None, 
       menu_icon_type=None, 
       menu_icon_value=None): 
     super(MergeAddressesView, self).__init__(name, 
              category, 
              endpoint, 
              url or '/admin', 
              'static', 
              menu_class_name=menu_class_name, 
              menu_icon_type=menu_icon_type, 
              menu_icon_value=menu_icon_value) 
     self._template = template 

    def is_visible(self): 
     return False 

    @expose('/', methods=['POST']) 
    def index(self): 
     if request.method == 'POST': 
      # get the original checked id's 
      ids = request.form.getlist('rowid') 

      merge_form = MergeAddressForm() 
      merge_form.process() 
      joined_ids = ','.join(ids) 
      encoded = base64.b64encode(joined_ids) 
      merge_form.ids.data = encoded 
      _return_url = request.args['return_url'] 
      merge_form.return_url.data = _return_url 
      self._template_args['form'] = merge_form 
      self._template_args['cancel_url'] = _return_url 
      return self.render(self._template) 

    @expose('/merge', methods=['POST']) 
    def merge(self): 

     if request.method == 'POST': 
      merge_form = MergeAddressForm(selection_choices=[]) 
      decoded = base64.b64decode(merge_form.ids.data) 
      ids = decoded.split(',') 
      # do the merging 
      address_merger = AddressMerger(ids=ids, primary_id=merge_form.primary_address.data) 
      address_merger.merge() 
      # return to the original flask-admin list view 
      return redirect(merge_form.return_url.data) 

我的用户输入表单模板如下所示。请注意动作网址。

{% extends 'admin/base.html' %} 
{% import "bootstrap/wtf.html" as wtf %} 

{% block body %} 
    <h3>{{ admin_view.name|title }}</h3> 
    <form role="form" action="{{ url_for('mergeaddresses.merge') }}" method="post" name="form"> 

     {{ form.hidden_tag() }} 

     {{ wtf.form_errors(form) }} 

     {{ wtf.form_field(form.primary_address) }} 

     <button type="submit" class="btn btn-primary">Merge</button> 
     <a href="{{ cancel_url }}" class="btn btn-danger" role="button">Cancel</a> 
    </form> 
{% endblock %}