gpt4 book ai didi

python - 在 Django 中模拟 POST 请求

转载 作者:太空狗 更新时间:2023-10-30 01:47:03 24 4
gpt4 key购买 nike

假设我有以下网址:/valid/django/app/path/?foo=bar&spam=eggs

我可以这样在 Django 中模拟对这个 URL 的请求:

from django.shortcuts import render
from django.core.urlresolvers import resolve

def simulate(request, url=None, template_name="not_important.html"):
if url:
dv = resolve(url.split('?')[0])
return dv.func(request, *dv.args, **dv.kwargs)
else:
return render(request, template_name)

但是,我想将参数包含到包含的 View 中,以便 request.REQUEST 和 request.GET 对象也将包含 foospam

我不知道如何干净利落地做到这一点;据我了解 request.GET 和 request.REQUEST 字典是不可变的,所以我不能只做类似的事情:

import urlparse

def simulate(request, url=None, template_name="not_important.html"):
if url:
dv = resolve(url.split('?')[0])
qs = "".join(url.split('?')[1:])
if qs:
request.REQUEST.update(urlparse.parse_qs(qs))
request.GET.update(urlparse.parse_qs(qs))
return dv.func(request, *dv.args, **dv.kwargs)
else:
return render(request, template_name)

否则我会得到错误信息

This QueryDict instance is immutable

对于 request.GET 对象和

'MergeDict' object has no attribute 'update'

对于request.REQUEST对象

万一有人想知道我为什么要这样做:我想让用户填写一个表单,然后,当他们提交时,如果他们没有登录,它会将他们发送到一个包含原始表单的登录表单隐藏字段中的 URL。登录后,而不是重定向回该链接(这将是一个 GET 请求),我希望它使用它最初拥有的请求变量调用原始 View ,以便它可以使用相同的 POST 请求。

当然,在这个过程中,我也只对在给定站点的有效 URL 时是否可以模拟对 Django View 的 POST/GET 请求感兴趣。

最佳答案

request.GET/POST 是 QueryDict实例。根据 QueryDict 上的文档,确实存在“不可变”除非你克隆它们:

QueryDict instances are immutable, unless you create a copy() of them. That means you can't change attributes of request.POST and request.GET directly.

您可以像这样复制、更新和重新分配 QueryDicts:

ipdb> request.GET
<QueryDict: {u'x': [u'1']}>
ipdb> request.POST
<QueryDict: {}>
ipdb> request.REQUEST
MergeDict(<QueryDict: {}>, <QueryDict: {u'x': [u'1']}>)
ipdb> new_post = request.POST.copy()
ipdb> new_post.update(request.GET)
ipdb> request.POST = new_post
ipdb> request.POST
<QueryDict: {u'x': [u'1']}>
ipdb> request.GET
<QueryDict: {u'x': [u'1']}>
ipdb> request.REQUEST
MergeDict(<QueryDict: {}>, <QueryDict: {u'x': [u'1']}>)

更新 MergeDict 的诀窍是重写它的 dicts 属性:

ipdb> request.REQUEST
MergeDict(<QueryDict: {}>, <QueryDict: {u'x': [u'1']}>)
ipdb> request.REQUEST.dicts = (request.POST, request.GET)
ipdb> request.REQUEST
MergeDict(<QueryDict: {u'x': [u'1']}>, <QueryDict: {u'x': [u'1']}>)

请注意,MergeDict 在模块 django.utils.datastructures 中定义,并在 django.core.handlers.wsgi(和 django .core.handlers.modpython) 这样:self._request = datastructures.MergeDict(self.POST, self.GET)

免责声明:MergeDict 没有记录,有一天会崩溃,甚至可能杀死一些小猫。根据您的判断和您自己的小猫使用。也就是说,我喜欢您的用例,这是个不错的主意。

关于python - 在 Django 中模拟 POST 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9370090/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com