Django Admin满足条件删除对象后重定向至删除视图问题
解决Wagtail Snippet保存后删除对象的重定向问题
这个问题我之前也碰到过,核心原因是你在模型层处理了删除逻辑,但HTTP重定向是视图层的职责——模型的save()方法根本没办法返回HTTP响应,所以浏览器自然会停留在原来的编辑页面,而此时对象已经被删,就出现了错误页面。
要解决这个问题,我们需要从Wagtail的snippet编辑视图入手,自定义它的保存逻辑,在满足条件时直接重定向到正确的页面。
具体实现步骤
1. 自定义Snippet编辑视图
Wagtail允许我们通过继承EditView来重写snippet的编辑逻辑,重点是重写form_valid()方法——这个方法负责处理表单验证通过后的操作,我们可以在这里加入条件判断和重定向逻辑。
from wagtail.snippets.views.snippets import SnippetViewSet from wagtail.admin.views.generic.edit import EditView from .models import MyModel class CustomMyModelEditView(EditView): def form_valid(self, form): # 获取表单绑定的实例(还未保存到数据库) instance = form.save(commit=False) # 替换成你的条件判断逻辑 condition = # 比如 instance.status == "expired" if condition: # 注意:如果是新创建的对象(还没有pk),直接delete会报错,所以先判断 if instance.pk: instance.delete() # 重定向到snippet列表页(你也可以改成其他页面,比如自定义的成功页) return self.redirect_to_list() else: # 正常保存并执行默认的重定向逻辑 return super().form_valid(form) # 自定义Snippet的ViewSet,指定我们的编辑视图 class MyModelSnippetViewSet(SnippetViewSet): model = MyModel edit_view_class = CustomMyModelEditView
2. 注册自定义的Snippet ViewSet
在你的app的wagtail_hooks.py文件中,注册这个自定义的ViewSet,替换默认的snippet注册方式:
from wagtail.snippets.models import register_snippet from .views import MyModelSnippetViewSet register_snippet(MyModelSnippetViewSet)
为什么原来的方法不行?
你之前在模型save()里调用self.delete(),确实能删除对象,但Wagtail的默认编辑视图在执行完save()后,会尝试重定向到该对象的编辑页面(也就是/snippets/myapp/mymodel/1234/),而此时对象已经不存在,所以服务器返回404错误。
通过在视图层处理,我们可以在删除对象后直接跳转到列表页,避免浏览器访问已不存在的URL。
额外注意点
- 处理新创建的对象:如果是刚创建的snippet(还没点击过保存,没有生成pk),直接调用
delete()会抛出异常,所以一定要先判断instance.pk是否存在。 - 条件判断逻辑:确保你的
condition逻辑和原来模型里的一致,避免出现行为不一致的情况。
内容的提问来源于stack exchange,提问作者Pablo Viacheslav
相关产品推荐
相关产品推荐

