Jor*_*ter 4 python django django-urls django-views
我们假设我有以下网址: /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)
Run Code Online (Sandbox Code Playgroud)
但是,我想将参数包含在包含的视图中,以便request.REQUEST和request.GET对象也包含foo和spam
我看不出我怎么能干净利落地做到这一点; 据我所知,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)
Run Code Online (Sandbox Code Playgroud)
或者我会收到错误消息
此QueryDict实例是不可变的
对于request.GET对象和
'MergeDict'对象没有属性'update'
对于request.REQUEST对象
如果有人想知道我为什么要这样做:我想允许用户填写表单,然后,当他们提交时,如果他们没有登录,它会将它们发送到包含原始URL的登录表单隐藏的领域.登录后,而不是重定向回到该链接(这将是一个GET请求),我希望它使用它最初具有的请求变量来调用原始视图,以便它可以使用相同的POST请求.
当然,在这个过程中,我也只是感兴趣的是,当给出该网站的有效URL时,是否可以模拟对Django视图的POST/GET请求.
jpi*_*pic 14
request.GET/POST是QueryDict实例.根据QueryDict上的文档,除非你克隆它们,否则确实是"不可变的" :
QueryDict实例是不可变的,除非您创建它们的副本().这意味着您无法直接更改request.POST和request.GET的属性.
您可以复制,更新和重新分配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']}>)
Run Code Online (Sandbox Code Playgroud)
更新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']}>)
Run Code Online (Sandbox Code Playgroud)
请注意,MergeDict在模块django.utils.datastructures中定义,并在django.core.handlers.wsgi(和django.core.handlers.modpython)中实现,如下所示:self._request = datastructures.MergeDict(self.POST, self.GET).
DISCLAMER:MergeDict没有记录,有一天会破坏,甚至可能会杀死一些小猫.您可以自行决定使用自己的小猫.这就是说我喜欢你的用例,这是个不错的主意.