django重定向到CreateView之后的上一个url

django重定向到CreateView之后的上一个url,django,django-forms,Django,Django Forms,我想返回到提交后调用CreateView、UpdateView和DeleteView的DetailView(BuildingUnitDetail)的url。例: 我还发现了一些关于重定向到上一个视图的其他问题/答案,但我无法找到任何适合我的解决方案。主要是因为我不理解他们。看来这应该是一个直截了当的解决方案,我想得太多了 有没有无痛的解决办法 任何帮助都会受到极大的欢迎,在这里已经超过2天了 #url.py #forms.py #表单模板 {% block content %} <form

我想返回到提交后调用CreateView、UpdateView和DeleteView的DetailView(BuildingUnitDetail)的url。例:

我还发现了一些关于重定向到上一个视图的其他问题/答案,但我无法找到任何适合我的解决方案。主要是因为我不理解他们。看来这应该是一个直截了当的解决方案,我想得太多了

有没有无痛的解决办法

任何帮助都会受到极大的欢迎,在这里已经超过2天了

#url.py

#forms.py

#表单模板

{% block content %}
<form method="POST"> {% csrf_token %}
    {{ form.as_p }}
    <input class="btn btn-danger" type="submit" value="Submit">
</form>
{% endblock content %}
{%block content%}
{%csrf_令牌%}
{{form.as_p}}
{%endblock内容%}

使用下一个参数可能是一个优雅的解决方案

下面是一个示例(我刚刚编写的未经测试的代码)。基本上,使用
get\u form\u kwargs
方法可以确保按钮参数在get时被推送到表单的初始dict。
form\u valid
方法扩展确保
success\u url
属性在POST数据中可用时重载

这样,您仍然可以以普通方式使用
success\u url
属性定义默认值

注意:您不能信任用户的输入。为了简单起见,我在下一个字段中使用了CharField。在现实生活中,您应该检查来自此字段的数据并对其进行验证

BuildingUnitDetail模板

<a href="{% url 'workorder_add' %}?next={% url 'building_unit_detail' object.pk %}">
    Add workorder
</a>  # assuming 'object' (Unit) is available in your template's context
CreateWorkOrder视图

class CreateWorkOrder(CreateView):
    template_name = 'cdpapp/workorder_form.html'
    form_class = WorkOrderForm

    def get_form_kwargs(self, **kwargs):
        kwargs = super(CreateWorkOrder, self).get_form_kwargs()
        redirect = self.request.GET.get('next')
        if redirect:
            if 'initial' in kwargs.keys():
                kwargs['initial'].update({'next': redirect})
            else:
                kwargs['initial'] = {'next': redirect}
        return kwargs

    def form_invalid(self, form):
        import pdb;pdb.set_trace()  # debug example
        # inspect the errors by typing the variable form.errors
        # in your command line debugger. See the pdb package for
        # more useful keystrokes
        return super(CreateWorkOrder, self).form_invalid(form)

    def form_valid(self, form):
        redirect = form.cleaned_data.get('next')
        if redirect:
            self.success_url = redirect
        return super(CreateWorkOrder, self).form_valid(form)
重新考虑?


为了避免重定向,您还可以在弹出窗口中处理这些“任务”,或者在单个视图中处理多个表单。这会增加复杂性,但后者可能会增强用户体验。

我想差不多了。next=forms.CharField(required=False)显示在表单上,并具有正确的重定向url。虽然我提交时,它既不重定向也不保存数据。@geomajor56在form_valid函数的顶部设置一个断点,然后查看传入的值是什么。如果未命中,请在form\u invalid中设置断点并检查
form.errors
。如果您不熟悉断点:如果您使用的是命令行调试器,则可以使用
import pdb;pdb.set_trace()
检查代码(使用
c
继续您的代码并跳出断点)请参见上面更新的示例我对断点不熟悉,但我会尝试解决它。我得到一个页面未找到错误。它保存了数据,但重定向错误是这个请求URL:保存的数据意味着您点击了
form\u valid
,这很好。查看下一个参数包含的内容,它直接来自已清理的表单,因此其值不能与您在表单中看到的值不同。我怀疑
self.success\u url
不知何故被
get\u success\u url
重载了。最初,我在这行redirect=self.cleaned\u data.get('next')中省略了“cleaned\u data”,因为我的IDE Pycharm说它是一个未解析的属性引用。然后它保存了数据。它还说“重定向”是“从外部范围重定向”。不知道那是什么意思。我是否缺少已清理的\u数据的导入?
{% block content %}
<form method="POST"> {% csrf_token %}
    {{ form.as_p }}
    <input class="btn btn-danger" type="submit" value="Submit">
</form>
{% endblock content %}
<a href="{% url 'workorder_add' %}?next={% url 'building_unit_detail' object.pk %}">
    Add workorder
</a>  # assuming 'object' (Unit) is available in your template's context
class WorkOrderForm(forms.ModelForm):
    next = forms.CharField(required=False)

    class Meta:
        model = WorkOrder
        exclude = tuple()
class CreateWorkOrder(CreateView):
    template_name = 'cdpapp/workorder_form.html'
    form_class = WorkOrderForm

    def get_form_kwargs(self, **kwargs):
        kwargs = super(CreateWorkOrder, self).get_form_kwargs()
        redirect = self.request.GET.get('next')
        if redirect:
            if 'initial' in kwargs.keys():
                kwargs['initial'].update({'next': redirect})
            else:
                kwargs['initial'] = {'next': redirect}
        return kwargs

    def form_invalid(self, form):
        import pdb;pdb.set_trace()  # debug example
        # inspect the errors by typing the variable form.errors
        # in your command line debugger. See the pdb package for
        # more useful keystrokes
        return super(CreateWorkOrder, self).form_invalid(form)

    def form_valid(self, form):
        redirect = form.cleaned_data.get('next')
        if redirect:
            self.success_url = redirect
        return super(CreateWorkOrder, self).form_valid(form)