我在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>
答案 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>