Flask Admin-有没有办法存储表格视图的当前URL应用自定义过滤器?

问题描述

我正在Flask Admin中开发票务系统。 Flask Admin环境将是所有用户的主要环境。为了创建或编辑票证,我从Flask-Admin出去,并使用wtforms实现后端逻辑。创建或编辑故障单(validate_on_submit)后,我想重定向回Flask Admin,所以我使用redirect(url_for(ticket.index_view))。很好。

是否可以重定向到flask admin,而且还可以使用在用户离开Flask admin环境之前应用的特定过滤器? (基本上是url的GET参数-但在FLASK中)

我正在尝试使用:

  • referrer = request.referrer
    
  • get_url()

但是我可能缺少了一些关键的东西,不知道如何实现(放在哪里,以便我可以调用参数)

非常感谢您。

编辑:添加更多上下文:

我有一个烧瓶管理员根据用户的不同角色进行了自定义。主要的ModelView是一个显示票证的类:类的细节对于我当前的问题并不重要,但在这里它的外观如下:

class TicketModelView(ModelView):
    column_list = ['id','title','osoba','content','povod_vmc_kom','dateVMC','zodpovedni','deadline','odpoved','solution','is_finished']
    column_searchable_list = ['osoba']

    column_filters = [ 'povod_vmc_kom','zodpovedni']
    column_labels = dict(povod_vmc_kom='VMČ / Komisia',dateVMC='Dátum VMČ / komisie',zodpovedni = "Zodpovední")
    column_display_actions = True
    column_filters = [
        FilterEqual(column=Ticket.povod_vmc_kom,name='Výbor/komisia',options=(('VMČ Juh','VMČ Juh'),('UM','UM'),('Kom dopravy','Kom dopravy'))),'is_finished','osoba'
        ]

    def is_accessible(self):

        #práva pre vedenie mesta - môže len nazerať
        if current_user.is_authenticated and current_user.role == 0:
            self.can_export=True
            self.can_delete = False
            self.can_edit = False
            self.can_create = False
            self._refresh_form_rules_cache()
            self._refresh_forms_cache()
            return True
        #práva pre super admina (ostatné práva sú defaultne zapnuté)
        if current_user.is_authenticated and current_user.role == 1:
            self.can_export=True
            self.can_delete=True
            self.form_edit_rules = ('zodpovedni','is_finished' )
            self.column_editable_list = ['is_finished']
            self._refresh_form_rules_cache()
            self._refresh_forms_cache()
            return True
        #práva pre garantov
        if current_user.is_authenticated and current_user.role == 2:
            self.can_delete = False
            self.can_create = False
            self.can_edit = False
            self.can_export=True
            self.column_searchable_list = ['title']


            self._refresh_form_rules_cache()
            self._refresh_forms_cache()

            return True
        #práva pre veducich utvarov
        if current_user.is_authenticated and current_user.role == 3:
            self.can_create = False
            self.can_delete = False
            self.can_export=True
            self.column_searchable_list = ['title']
            self.column_editable_list = ['odpoved','date_odpoved','date_solution' ]
            self.form_edit_rules = ('odpoved','date_solution')
            self._refresh_form_rules_cache()
            self._refresh_forms_cache()
            return True
        return False
            

    def _solution_formatter(view,context,model,name):
        # Format your string here e.g show first 20 characters
        # can return any valid HTML e.g. a link to another view to show the detail or a popup window
        if model.solution:
            return model.solution[:50]
        pass
    def _content_formatter(view,name):
        # Format your string here e.g show first 20 characters
        # can return any valid HTML e.g. a link to another view to show the detail or a popup window
        if len(model.content) > 100:
            markupstring = "<a href= '%s'>%s</a>" % (url_for('ticket',ticket_id=model.id),"...")
            return model.content[:100] + Markup(markupstring)
        return model.content
    def _user_formatter(view,name):
        if model.id:
           markupstring = "<a href= '%s'>%s</a>" % (url_for('ticket',model.id)
           return Markup(markupstring)
        else:
           return ""
    column_formatters = {
        'content': _content_formatter,'solution': _solution_formatter,'id': _user_formatter
    }

用户在Flask Admin中查看TicketView时,他可以应用各种过滤器,这对于整个Web应用程序的用户体验至关重要。过滤器工作正常,它们作为GET参数存储在URL中。当他想要创建或编辑故障单时,我不允许他在Flask Admin中进行操作(我编辑了Flask-Admin layout.html模板,为导航栏添加一个按钮,该按钮使用wtforms重定向到我的new_ticket网址。)由于我想应用后端逻辑,例如,当他编辑字段“ solution”时:我希望字段“ date_of_solution”中的值自动生成(date.today())。所以我使用wtforms和flask路由:下面是示例:

@app.route("/ticket/<int:ticket_id>/solution",methods = ['GET','POST'])
@login_required
def solution(ticket_id):
    if current_user.role != 3:
        flash("Pre zadanie riešenia alebo odpovede musíte byť prihlásený ako vedúci útvaru","danger")
        return redirect(url_for('ticket',ticket_id=ticket_id))
    ticket = Ticket.query.get_or_404(ticket_id)
    form = AdminPanelForm()

    if form.validate_on_submit():
        print("1")
        if not ticket.date_solution:
            print("2")
            ticket.date_solution= datetime.Now()
        if not ticket.date_odpoved:
            print("3")
            if form.odpoved.data != ticket.odpoved:
                print("4")
                ticket.date_odpoved= datetime.Now()
        ticket.solution = form.solution.data
        ticket.odpoved = form.odpoved.data
        ticket.is_finished = True
        db.session.commit()
        flash("Ticket bol updatenutý","success")
        **return redirect(url_for('ticketmod.index_view'))**
    elif request.method == 'GET':

        form.solution.data = ticket.solution
        form.odpoved.data = ticket.odpoved
    return render_template("admin_ticket.html",form=form,ticket = ticket)

现在您可以看到成功更新票证后,用户重定向到他来自的票证模型视图return redirect(url_for('ticketmod.index_view')),但未应用过滤器。我正在寻找解决方案,如何存储url GET参数(过滤器),然后在重定向回ModelView时使用它们。我尝试了get_url()或request.referrer函数,但没有成功。

正如我在原始帖子中所说,也许我错过了Web体系结构中的一些重要内容-如果您有一些学习材料,我应该关注:谢谢您的任何建议。

解决方法

在formatter方法内,您可以使用以下方法获取包含应用的过滤器/排序条件的视图的URL:

_view_url = view.get_url('.index_view',**request.args)

现在将此作为参数或其他方式传递给路由请求。例如:

class TicketModelView(ModelView):

    #  blah blah

     def _user_formatter(view,context,model,name):
        if model.id:
            #  This is the current url of the view including filters
            _view_url = view.get_url('.index_view',**request.args)
            # Pass this as a parameter to your route
           markupstring = "<a href= '%s'>%s</a>" % (url_for('ticket',ticket_id=model.id,return_url=_view_url),model.id)
           return Markup(markupstring)

在该路线上,您现在可以从请求arg中提取return_url并将其添加为表单中的隐藏字段。然后在回发中从表单中检索值并重定向。

@app.route("/ticket/<int:ticket_id>/solution",methods = ['GET','POST'])
@login_required
def solution(ticket_id):
    #  Get the return_url from the request
    _return_url = request.args.get('return_url'):

    #  Add the return_url to the form as a hidden field
    form.return_url.data = _return_url

    #  blah blah

    if form.validate_on_submit():
        #  get return value from form
        _return_url = form.return_url.data

        return redirect(_return_url) if _return_url else redirect(url_for('ticketmod.index_view'))