【问题标题】:Django redirect back to previous page on form postDjango 在表单发布时重定向回上一页
【发布时间】:2015-08-10 01:36:32
【问题描述】:

我正在尝试将表单发布重定向回发布它的页面。所以我的应用程序有一个详细信息页面,显示有关地点的信息,/arena/123,在同一页面上,用户可以输入一些关于他们正在查看的当前地点的 cmets 或评级。这些是我的视图函数。

class DetailView(LoginRequiredMixin, generic.DetailView):
    model = Arena
    template_name = 'arenas/detail.html'

    def get_context_data(self, **kwargs):
        context = super(DetailView, self).get_context_data(**kwargs)
        if 'form' not in context:
            print 'no form in context'
            context['form'] = RatingForm
        return context

def rate(request):
    if request.method == 'POST':
        form = RatingForm(request.POST)
        if form.is_valid():
            # post was valid. go back to page and display data
            return DetailView.as_view()(request(), form=RatingForm)
        else:
            # post was unsuccessful. go back to the page and display errors
            print form.errors
            return DetailView.as_view()(request(), form=form)

还有我的模板

{% extends "base.html" %}
{% block content %}
    <h1>{{ arena.address }}</h1>
    <h1>{{ arena.address_2 }}</h1>
    <h1>{{ arena.phone }}</h1>

    {% if form.errors %}
        {% for field in form %}
            {% for error in field.errors %}
                <div class="alert alert-error">
                    <strong>{{ error|escape }}</strong>
                </div>
            {% endfor %}
        {% endfor %}
        {% for error in form.non_field_errors %}
            <div class="alert alert-error">
                <strong>{{ error|escape }}</strong>
            </div>
        {% endfor %}
    {% endif %}
    <form action="/arenas/rate/" method="post">
        {% csrf_token %}
        {{ form }}
    <input type="submit" value="Submit" />
    </form>

    <div>
        {{comments}}
    </div>
{% endblock %}

所以我想做的是,在用户在页面上提交表单后,我想返回到我所在的同一详细信息页面,或者在 cmets 部分中显示用户在那里发布的数据如果它成功或重定向回同一页面,但如果它不成功,则会出现表单错误。我的问题是现在我不知道如何保留 url 和表单错误以再次显示详细信息页面。我认为我不能使用return DetailView.as_view()(context(), form=form),因为我的 DetailView 没有帖子,所以我得到了 405。我看到的每个示例都不包括重定向回同一页面。他们通常只显示HttpResponseRedirect(/thanks) 或类似的东西。

还要注意。我不想发布到 /arena/123,因为最终这将是更新该地点信息的另一个功能,所以我不想将 cmets 发布到该 URL 上。

【问题讨论】:

    标签: python django


    【解决方案1】:

    所以我挖掘了更多 Django 示例并偶然发现了SingleObjectMixin。这与FormView 相结合似乎是我想要的。 Django 文档有一个例子,这是我想要的 99.9% here。请务必仔细阅读better solution 部分。

    我改变了对这个的看法

    class DetailView(LoginRequiredMixin, generic.DetailView):
        model = Arena
        template_name = 'arenas/detail.html'
    
        def get_context_data(self, **kwargs):
            print kwargs
            context = super(DetailView, self).get_context_data(**kwargs)
            context['form'] = RatingForm
            return context
    
    
    class RatingView(LoginRequiredMixin, detail.SingleObjectMixin, generic.FormView):
        model = Arena
        template_name = 'arenas/detail.html'
        form_class = RatingForm
    
        def post(self, request, *args, **kwargs):
            self.object = self.get_object()
            return super(RatingView, self).post(request, *args, **kwargs)
    
        def get_success_url(self):
            print "successfully posted"
            return reverse('arenas:detail', kwargs={'pk': self.object.pk})
    

    添加了使用 /rate 发布表单的路线

    urlpatterns = patterns('',
                           url(r'^$', views.IndexView.as_view(), name='index'),
                           url(r'^(?P<pk>\d+)/$',
                               views.DetailView.as_view(), name='detail'),
                           url(r'^(?P<pk>\d+)/rate/$', views.RatingView.as_view(), name='rate')
                           )
    

    并稍微修改了我的模板以将对象的id 以表单发布操作的形式传递给我的路由

    {% extends "base.html" %}
    {% block content %}
        <h1>{{ arena.address }}</h1>
        <h1>{{ arena.address_2 }}</h1>
        <h1>{{ arena.phone }}</h1>
    
        {% if form.errors %}
            {% for field in form %}
                {% for error in field.errors %}
                    <div class="alert alert-error">
                        <strong>{{ error|escape }}</strong>
                    </div>
                {% endfor %}
            {% endfor %}
            {% for error in form.non_field_errors %}
                <div class="alert alert-error">
                    <strong>{{ error|escape }}</strong>
                </div>
            {% endfor %}
        {% endif %}
        <form action="/arenas/{{ arena.id }}/rate/" method="post">
            {% csrf_token %}
            {{ form }}
        <input type="submit" value="Submit" />
        </form>
    
        <div>
            {{comments}}
        </div>
    {% endblock %}
    

    现在,如果出现错误,则会保留上下文,SingleObjectMixin/FormView 组合让我在同一页面上显示表单错误,并在成功发布时重定向到我想要使用 get_success_url 加载页面的详细信息页面再次使用已发布的新信息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-03
      • 2023-03-03
      • 2012-07-16
      • 2014-11-24
      • 1970-01-01
      • 2021-09-03
      • 2020-06-20
      • 2015-09-12
      相关资源
      最近更新 更多