繁体   English   中英

POST后的Django表单重定向不可靠,需要success_url

[英]Django form redirect after POST is unreliable and needed a success_url

我完全不了解这种行为,并发现了我不太喜欢的解决方法。 谁能帮我启发? 上下文是我有一个引导样式的窗体来创建新记录(继承自generic.CreateView)

url.py:

url(r'^$', home, name='home'),
url(r'^main/$', views.MainView.as_view(), name='MainView'),
url(r'^topic/(?P<pk>[0-9]+)/$', catalogue_views.TopicView.as_view(), name='TopicView'),
url(r'^resource/(?P<pk>[0-9]+)/$', catalogue_views.DetailView.as_view(), name='ResourceDetail'),
url(r'^contribute/$', catalogue_views.ContributeView.as_view(success_url="/main/"), name='Contribute'),

views.py:

class ContributeView(generic.CreateView):
    template_name = "openeye/contribute.html"
    form_class = ContributeForm

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(ContributeView, self).dispatch(*args, **kwargs)

class MainView(generic.ListView):

    template_name = "openeye/main.html"
    context_object_name = 'topic_list'

    # TODO Make this only active topic areas?
    def get_queryset(self):
        return TopicArea.objects.all().order_by('name')

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(MainView, self).dispatch(*args, **kwargs)

forms.py:

class ContributeForm(forms.ModelForm):
    class Meta:
        model = CatalogueItem
        fields = ['title', 'topic_area', 'description', 'link', 'what_learn', 'how_apply', 'level', 'relevant_to', 'discovered_by']

    ROLE_CHOICES = [[x.id, x.job] for x in JobType.objects.all()]

    title = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'To sell this resource to others'}), max_length=80, required=True)
    description = forms.CharField(widget=forms.Textarea(attrs={'rows': 2, 'placeholder': 'Clear, e.g. format, duration, activities...'}))
    link = forms.CharField(widget=forms.URLInput(attrs={'placeholder': 'If required, link to resource http://...'}), required=False)
    what_learn = forms.CharField(widget=forms.Textarea(attrs={'rows': 3, 'placeholder':"This is important,."}), label='What will you learn?')
    how_apply = forms.CharField(widget=forms.Textarea(attrs={'rows': 3, 'placeholder':"How could this be put into action afterwards?"}), label='How could you apply this?')
    relevant_to = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=ROLE_CHOICES)

和具有形式的模板:

<div class="container">
        <div class="entry-form row">
            <div class="col-md-10 col-md-offset-1 col-sm-10 col-sm-offset-1 col-xs-10 col-xs-offset-1">
                <form action="{% url 'MainView' %}" method="post" class="form">
                    <input type="hidden" name="next" value="{{ next }}">
                    {% bootstrap_form form %}
                    <button class="btn btn-primary btn-lg" type="submit">Submit Suggestion</button>
                    {% csrf_token %}
                </form>
        </div>
    </div>

表单运行完美,数据很好地保存到数据库中。 问题出在那之后,浏览器转到正确的URL / main /,但是屏幕是空白的。 服务器显示HTTP 405 0,并且如果刷新页面,它将起作用。

如果我更改模板,使action =“ {%url'Contribute'%}”返回相同的格式,则会收到HTTP 500和Django消息“ No URL to redirect to”。 因此两个不同的错误由重定向位置确定。 在这两种情况下,如果我只单击浏览器URL字段并单击return都可以。

我确信这最初是可行的,然后又解决了,但我按以下方法解决了。 使用成功路径中的成功代码中的硬代码

url(r'^contribute/$', catalogue_views.ContributeView.as_view(success_url="/main/"), name='Contribute'),

删除模板中的任何操作链接:

<form action="" method="post" class="form">

这是正确的方法吗? 为什么,尽管使用了正确的URL,但页面仍无法按我的原始方法加载或出现错误? 我很想了解这一点。

您确定您的数据实际上已保存在服务器上吗? 从您发布的内容来看,似乎不太可能。 这是Django遵循的正常过程:

  1. 在表单视图上获取(ContributeView)→返回一个空表单
  2. 在表单视图(ContributeView)上进行POST→如果无效,请返回到步骤1。如果有效,则将302 Redirect返回至success_url
  3. 获取关于success_url的信息

因此,通常,在您的模板中,表单操作应为空,以便将表单发布回生成它的视图。 并且ContributeView应该具有一个成功URL,该URL可以重定向到您希望在之后将用户发送到的任何位置:

from django.core.urlresolvers import reverse_lazy
class ContributeView(generic.CreateView):
    # other stuff
    success_url = reverse_lazy('MainView')

使用405,您得到的行为是因为浏览器尝试将表单直接发送到MainView ,而MainView不是表单视图,告诉浏览器它不知道如何处理POST方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM