You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中UpdateView提交成功后如何返回带原有筛选参数的TableView页面

现有代码问题说明

首先修正一个代码错误:Django 通用视图的get_success_url方法本身不需要接收form参数,你当前的写法不符合官方方法签名,可能引发参数不匹配错误。
你之前的尝试不生效的核心原因是:get_context_data中拿到的referrer是用户第一次进入编辑页的来源地址(也就是带筛选参数的列表页),但提交表单时触发的是POST请求,此时self.request.META.get('HTTP_REFERER')的值已经变成了编辑页本身的地址,所以直接在get_success_url中读取当前请求的referrer是无效的。


解决方案

方案1:通过表单隐藏字段传递跳转地址(更稳定,不受session过期影响)

步骤1:模板新增隐藏字段

在UpdateView对应的模板表单内,添加如下隐藏输入框,将你从get_context_data传递到模板的referrer作为参数提交:

<form method="post">
    {% csrf_token %}
    <!-- 新增隐藏字段 -->
    <input type="hidden" name="next" value="{{ referrer|default:'{% url "sale_list" %}' }}">
    <!-- 原有表单内容 -->
    {{ form.as_p }}
    <button type="submit">提交</button>
</form>

步骤2:修改get_success_url逻辑

直接读取POST请求中的next参数作为跳转地址,兜底跳转到无筛选的列表页:

from django.utils.http import is_safe_url

def get_success_url(self):
    next_url = self.request.POST.get('next')
    # 校验跳转地址为本站地址,避免开放重定向漏洞
    if next_url and is_safe_url(url=next_url, allowed_hosts={self.request.get_host()}):
        return next_url
    return reverse_lazy('sale_list')

原有form_valid逻辑无需修改,保持原有即可。


方案2:通过session存储跳转地址(无需修改模板)

如果不想改动模板,可以在GET请求进入编辑页时,将来源地址存入session,提交成功后从session读取地址跳转:

步骤1:重写get方法存储来源地址

def get(self, request, *args, **kwargs):
    # 仅GET请求时存储来源页,避免POST请求覆盖原始来源
    referrer = request.META.get('HTTP_REFERER')
    if referrer:
        request.session['sale_edit_referrer'] = referrer
    return super().get(request, *args, **kwargs)

步骤2:修改get_success_url逻辑

from django.utils.http import is_safe_url

def get_success_url(self):
    # 从session弹出地址,避免残留
    next_url = self.request.session.pop('sale_edit_referrer', None)
    if next_url and is_safe_url(url=next_url, allowed_hosts={self.request.get_host()}):
        return next_url
    return reverse_lazy('sale_list')

内容的提问来源于stack exchange,提问作者Iván Flores Vázquez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 00:27:02