如何将 Django HttpResponse 转换为 Django 渲染调用
我有以下
def ajax_login_request(request):
try:
request.POST[u'login']
dictionary = request.POST
except:
dictionary = request.GET
user = authenticate(username = dictionary[u'login'], password = dictionary[u'password'])
if user and user.is_active:
login(request, user)
result = True
else:
result = False
response = HttpResponse(json.dumps(result), mimetype = u'application/json')
return response
通过 ajax 调用的代码。我是菜鸟,这是书中的一个例子。不幸的是,我使用的 Django 版本会引发 CSRF 错误。我已经完成了其他 CSRF 位,但我不知道如何将 HttpResponse 位更改为渲染调用。我不想使用 CSRF_exempt,因为我不知道什么时候合适。有人可以为我提供上述 HttpResponse 的等效渲染调用吗?
谢谢
I have the following code
def ajax_login_request(request):
try:
request.POST[u'login']
dictionary = request.POST
except:
dictionary = request.GET
user = authenticate(username = dictionary[u'login'], password = dictionary[u'password'])
if user and user.is_active:
login(request, user)
result = True
else:
result = False
response = HttpResponse(json.dumps(result), mimetype = u'application/json')
return response
which is being called via ajax. I'm a noob and this is from an example in a book. Unfortunately the version of Django I'm using throws a CSRF error on this. I've done the other CSRF bits, but I don't know how to change the HttpResponse bit to a render call. I do not want to use CSRF_exempt, because I have no idea when that is appropriate. Can someone please provide me the equivalent render call for the HttpResponse above.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为了使您的原始代码正常工作,您需要获取一个 RequestContext 对象并将其与您的响应一起传递,如下所示:
请阅读 CSRF 文档,因为如果您不了解 CSRF 在应用程序中“连接”的所有方式,您可能会遇到奇怪的错误。该页面还有一个 javascript 片段,以确保在您没有表单的情况下发送 CSRF cookie 时与您的 ajax 请求一起发送。
您还可以使用 render_to_response()快捷方式,但您需要加载一个实际的模板(在您的情况下,您不需要模板,因此在我的示例中使用“虚拟”模板)。
To make your original code work, you need to get a RequestContext object and pass it along with your response, something like this:
Do read up on the CSRF documentation as you might run into strange errors if you don't understand all the ways CSRF is "wired" in your app. The page also has a javascript snippet to make sure CSRF cookies are sent with your ajax requests if you are sending them without a form.
You can also use the render_to_response() shortcut, but you would need to have an actual template to load (in your case, you don't need a template, hence the "dummy" template in my example).
好的,我将重新起草这个答案,以便您了解我的观点。 CSRF 中间件的工作原理如下:
换句话说,如果您看到 403 csrf 页面,则您的视图从未被调用。您可以通过在视图中粘贴虚假打印语句并在发出请求时观察
runserver
的输出来确认这一点。要解决此问题,您需要禁用 csrf (不好)或使用 其中一种 ajax 方法可供您使用。如果所需的令牌在您的视图中传递,则会实际执行。
不调用视图的原因是为了防止伪造站点的操作实际发生 - 例如,如果您在响应时拒绝模板,则用户将已经登录。函数装饰器也会发生相同的行为。
至于设置 cookie 的中间件,它根本不会改变或依赖于渲染函数 - 这会在响应中设置 HTTP 标头
Cookie: ...
。 Django 中的所有响应都是 HttpResponse 对象,直到最终将它们转换为输出;render
函数是帮助器,但这并不是导致您出现问题的原因。编辑我会将您所获得的内容转换为渲染调用。您可以这样做:
其中
ajax_templates/login_response.html
只是:就是这样。
HttpResponse
有一个主要的默认参数,它是要返回的字符串(字面意思是网页的 html);这就是你最初所做的。render_to_response
和render
是执行此操作的快捷方式:Ok, I'm going to re-draft this answer so you understand where I'm coming from. The CSRF middleware works like this:
In other words, if you are seeing a 403 csrf page, your view was never called. You can confirm this by sticking a spurious print statement in the view and watching the output from
runserver
when you make your request.To solve this, you either need to disable csrf (not good) or use one of the ajax methods available to you. If the required token is passed in your view will actually be executed.
The reason your view is not called is to prevent the action from the forged site from actually ever taking place - for example, if you denied the template at response time the user would already be logged in. The same behaviour occurs with the function decorators.
As for the middleware setting the cookie, that does not alter or depend on the render function at all - this sets the HTTP header
Cookie: ...
in the response. All responses in Django areHttpResponse
objects until it finally converts them to output;render
functions are helpers, but that's not what's causing your problem here.Edit I'll convert what you've got to a render call. You could do this:
Where
ajax_templates/login_response.html
is just:That's it.
HttpResponse
has a main default argument which is the string to return (literally, the html of the web page); that's what you're doing initially.render_to_response
andrender
are shortcuts to this which do this: