[英]Simulating a POST request in Django
我們假設我有以下網址: /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)
但是,我想將參數包含在包含的視圖中,以便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)
或者我會收到錯誤消息
此QueryDict實例是不可變的
對於request.GET對象和
'MergeDict'對象沒有屬性'update'
對於request.REQUEST對象
如果有人想知道我為什么要這樣做:我想允許用戶填寫表單然后,當他們提交時,如果他們沒有登錄,它會將它們發送到包含原始URL的登錄表單隱藏的領域。 登錄后,而不是重定向回到該鏈接(這將是一個GET請求),我希望它使用它最初具有的請求變量來調用原始視圖,以便它可以使用相同的POST請求。
當然,在這個過程中,我也只是感興趣的是,當給出該網站的有效URL時,是否可以模擬對Django視圖的POST / GET請求。
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']}>)
更新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)
。
DISCLAMER :MergeDict沒有記錄,有一天會破壞,甚至可能會殺死一些小貓 。 您可以自行決定使用自己的小貓。 這就是說我喜歡你的用例,這是個不錯的主意。
它確實比request.GET / POST是不可變對象,但實際上你可以將它們變為可變(這有潛在危險)並直接更改它們,如下所示:
request.GET._mutable = True
# make some changes, for example delete something inside
if 'var_name' in request.GET:
del request.GET['var_name']
request.GET._mutable = False
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.