基于django类的视图post方法不能从其他方法中读取

时间:2017-03-20 14:50:48

标签: django django-class-based-views

我在django上运行一个基于分类的视图。我的post方法没有采用类中的其他方法,这很奇怪。

我的get_context_data工作,可以接受并打印self.get_msg(),但是,当我运行它时,我的post方法,它带我到一个页面找不到404页面,因为我的self.get_msg()函数包含在帖子功能中。我需要post函数来获取一些参数,这样我就可以将它保存在模型中。

有谁知道为什么会出现这种情况,我该如何解决这个问题?欢迎任何建议。

谢谢

class OpeningConfirmApp(LoginRequiredMixin, FormMixin, TemplateView):
    template_name = 'opening/opening_confirm_app.html'
    form_class = PriceForm

    def get_msg(self, *args, **kwargs):
        msg_id = self.request.GET.get("msg_id")
        msg = get_object_or_404(Message, pk=msg_id)
        parent_msg_id = msg.parent_id
        msg = get_object_or_404(Message, pk=parent_msg_id)
        return msg

    def get_context_data(self, *args, **kwargs):
        context = super(OpeningConfirmApp, self).get_context_data(*args, **kwargs)
        #working
        print self.get_msg()

        return context

    def post(self, request, *args, **kwargs):

        #not working
        print self.get_msg()

        form = self.get_form()
        if form.is_valid():
            price = form.cleaned_data.get("price")
            return self.form_valid(form)

    def get_success_url(self):
        msg = self.get_msg()
        messages.success(self.request, "Your application has been sent.")
        return reverse('MessageDetail', kwargs={'pk': msg.id})
如果有帮助,

下面是我的HTML。

<br>
<form action="{% url 'OpeningConfirmApp' %}" method="get" style="display: inline">
<input type="hidden" name="msg_id" value="{{object.id}}">
<input class='btn btn-success' type="submit" value="Apply for Opening">
</form>
<br>

3 个答案:

答案 0 :(得分:1)

您的get_msg()方法尝试从msg_id获取request.GET。此密钥不会在POST请求中设置,因此msg_id将为None,因此get_object_or_404将会提升。

这里的规范解决方案是传递&#34; msg_id&#34;作为网址的一部分而不是作为GET参数。你的url正则表达式看起来像

 r"/msg/something/(?P<msg_id>\d+)/$", 

你得到&#34; msg_id&#34;无论请求方法如何,在你看来的kwargs中。

如果您确实需要将其作为请求参数,那么您需要将其传递回实际发布到您视图的表单(您只在此处显示了执行GET请求的表单)。

答案 1 :(得分:1)

你不希望你的表单有一个post方法而不是get?

<form action="{% url 'OpeningConfirmApp' %}" method="POST" style="display: inline">

否则它根本无法进入你的POST方法。 (这可能就是为什么你没有看到post方法的print语句)。

正如Bruno所说,你的get_msg方法从request.GET而不是request.POST获取数据,所以你需要检查两者。 (Django曾经提供了一个request.REQUEST方法来访问GET和POST词典,但我发现它已经从1.10开始删除了。)

答案 2 :(得分:0)

我在研究bruno desthuilliers给出的提示后找到了解决方案。这个解决方案要求我做另一个url和功能。新功能重定向到我的主要功能以进行发布。

我必须添加另一个url.py来收集基于第一个网址中的pk的msg_id。

url(r'^messagedetail/(?P<pk>[0-9]+)/appoffconf$', AppOffConf, name='AppOffConf'),

并向view.py添加另一个函数来记录会话,然后将其重定向到我的main函数。

def AppOffConf(request, pk):
    request.session["msg_id"] = pk
    return redirect("OpeningConfirmApp")

这样它就可以检索msg_id而不需要post和get(这会使我的提交变得复杂,wobbily_col提到访问GET和POST词典的request.REQUEST方法已经在1.10中删除了,这就是我正在使用的)我的因此,执行帖子的主要功能将更改为self.request.session.get(&#34; msg_id&#34;)而不是self.request.GET.get(&#34; msg_id&#34;)

class OpeningConfirmApp(LoginRequiredMixin, FormMixin, TemplateView):
    template_name = 'opening/opening_confirm_app.html'
    form_class = PriceForm

    def get_msg(self, *args, **kwargs):
        #changed from - msg_id = self.request.GET.get("msg_id")
        msg_id = self.request.session.get("msg_id")
        msg = get_object_or_404(Message, pk=msg_id)
        parent_msg_id = msg.parent_id
        msg = get_object_or_404(Message, pk=parent_msg_id)
        return msg

    def get_context_data(self, *args, **kwargs):
        context = super(OpeningConfirmApp, self).get_context_data(*args, **kwargs)
        #working
        print self.get_msg()

        return context

    def post(self, request, *args, **kwargs):

        #working now
        print self.get_msg()

        form = self.get_form()
        if form.is_valid():
            price = form.cleaned_data.get("price")
            return self.form_valid(form)

    def get_success_url(self):
        msg = self.get_msg()
        messages.success(self.request, "Your application has been sent.")
        return reverse('MessageDetail', kwargs={'pk': msg.id})

将html更改为将表单按钮指向第一个url / function,然后将其重定向到我的main函数以进行发布。

<form action='appoffconf' method="post" style="display: inline">{% csrf_token %}
<input type="hidden" name="msg_id" value="{{i.id}}">
<input class='btn btn-success buttonspace' type="submit" value="Select">
</form>