Flask Admin - 有没有办法存储 table 视图的当前 url(应用自定义过滤器)?

Flask Admin - is there a way to store current url (with custom filters applied) of table view?

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

有没有一种方法可以重定向到 Flask 管理员,而且还可以使用在用户离开 Flask 管理员环境之前应用的特定过滤器? (它基本上是 url 的 GET 参数 - 但在 FLASK 中)

我正在尝试使用:

但我可能遗漏了一些重要的东西并且不知道如何实现它(把它放在哪里以便我可以调用参数)

非常感谢。

编辑:添加更多上下文:

我有一个针对不同用户角色定制的 flask 管理员。主要的 ModelView 是显示 TICKETS 的那个:Class 的细节对我当前的问题并不重要,但它的外观如下:

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', 'dateVMC', 'osoba', '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'))),
        'zodpovedni', 'is_finished',

        'dateVMC', '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', 'solution', 'date_solution' ]
            self.form_edit_rules = ('odpoved', 'date_odpoved', 'solution', '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, 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 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, context, model, name):
        if model.id:
           markupstring = "<a href= '%s'>%s</a>" % (url_for('ticket', ticket_id=model.id), 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 url。)因为我想应用后端逻辑。例如,当他编辑字段“解决方案”时:我希望自动生成字段“date_of_solution”中的值 (date.today())。所以我正在使用 wtforms 和烧瓶路由:示例如下:

@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 但我没有成功。

正如我在原文 post 中所说,也许我遗漏了 Web 架构中的一些重要内容 - 如果您想要学习一些东西 material 我应该看看:感谢您的任何建议。

在格式化程序方法中,您可以获得视图的 url,包括使用以下应用的 filters/sorting 标准:

_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 并将其添加为表单中的隐藏字段。然后在 post 返回从表单中检索值并重定向。

@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'))