【问题标题】:django class based view returns empty string when POSTdjango 基于类的视图在 POST 时返回空字符串
【发布时间】:2013-03-01 06:33:00
【问题描述】:

演示:

from django.views.generic.base import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

class TestView(View):
    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return HttpResponse('haha')

urls.py 是

url(r'^test/', TestView.as_view()),

所以当 GET 时你可以看到 haha,但是当你做 POST 时你会得到一个空白页...

我在这里缺少什么?

编辑:澄清我在做什么。我正在编写一个 JSON 流 CURD 视图,我需要以各种方式解析 JSON。其中之一是当 ppl POST 具有特定模式的数据时,视图将分派到视图内的另一个方法并返回一些东西。但事实证明什么都没有返回。因此,我向您介绍了最小的 PoC。请帮助我我的代码出了什么问题。蒂亚!

顺便说一句possible related question

【问题讨论】:

    标签: python django post django-views django-class-based-views


    【解决方案1】:

    你需要实现它的post 方法。见Class based views

    from django.http import HttpResponse
    from django.views.generic import View
    
    class TestView(View):
    
        @method_decorator(csrf_exempt)
        def dispatch(self, *args, **kwargs):
            # do something
            return super(TestView, self).dispatch(*args, **kwargs)
    
        def post(self, request, *args, **kwargs):
           # do somthing
    
        def get(self, request, *args, **kwargs):
           return HttpResponse('Hello, World!')
    

    查看更多dispatchdocs

    默认实现将检查 HTTP 方法并尝试委托给与 HTTP 方法匹配的方法; GET 将委托给 get(),POST 委托给 post(),等等。

    所以之前你扰乱了上述逻辑,调用super 将允许dispatch 委托给post 方法。

    【讨论】:

    • 但是我需要重写自己的调度逻辑,添加def post也行不通。
    • 也许我错了,但是直接在 dispatch() 中返回 HttpResponse 有什么区别?我在我的问题中提供了一个最小的 POC。在我的情况下,调度处理的不仅仅是 getpost,但显然无论我在 HttpResponse 中输入什么,它总是返回空正文。
    • 尝试在“做某事”中返回并发布 URL,您将得到空白页面...我无法解释为什么甚至查看 django 源代码。
    【解决方案2】:

    我知道这并不能真正回答您的问题,但它可能会提供一种解决方法。我在 JSON 应用程序中使用的是当我想要两者的结果相同时向 get 方法发送一个帖子。比如:

    def get(self, request, *args, **kwargs):
        return HttpResponse('Ha!')
    
    def post(self. request, *args, **kwargs):
        return self.get(request, *args, **kwargs)
    

    单独调度。

    【讨论】:

      【解决方案3】:

      使用基于类的视图时最好的方法是不要从头开始编写自己的方法处理程序;相反,使用一个通用类作为基础,然后只修改处理您需要的方法。例如,如果您有一个需要通过 POST 提交的表单,您应该使用 FormView 作为基础,它处理 GET 和 POST 请求的响应。

      您不需要自己重写 post() 和/或 get() 方法;而是使用form_valid() 来定义提交表单时会发生什么:

      class TestView(FormView):
          form_class = MyForm
          success_url = "/your/return/url/"
          def form_valid(self, form):
              # do something
              return redirect(self.get_success_url())
      

      【讨论】:

      • 是的,谢谢,我知道这一点。在我的情况下,上传的不是表单,而是纯 JSON 数据(内容类型为 application/json),我编写了自己的 JSONCURDView 非常需要知道为什么 django 返回一个空白页给定dispatch 返回。
      • 正如 ahsan 所说,这可能是因为您已经覆盖了调度,因此您的 post 或 get 方法永远不会被调用。像他一样调用super 以恢复默认行为。
      • 嗯,如果我明确返回disptch(),为什么我们又需要self.get()self.post()?默认行为已被覆盖。
      • 要更详细地回答这个问题,我们应该深入研究 Django 代码,但最好遵循应用程序的设计方式,而不是寻找捷径。根据我的经验,直接入侵dispatch 会导致一些不可预知的副作用;我建议您首先尝试用尽所有标准方法(在这种情况下,使用处理基于类的视图行为的许多方法中的一些方法)并仅作为最后的手段诉诸低级更改。
      • 嗨,我深入研究了 Django 源代码并跟踪了每个系统调用,发现这是一个 nginx+uWSGi 错误。请参阅下面的答案。
      【解决方案4】:

      对不起,这是 uWSGI 和 nginx 中的一个错误......

      https://stackoverflow.com/a/11115108/41948

      非常抱歉误导您浪费了您的时间。我仍然花了一段时间才弄清楚我的堆栈的哪一部分出错了。

      【讨论】:

        猜你喜欢
        • 2013-06-30
        • 2019-10-28
        • 2016-08-19
        • 2014-09-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多