创建虚假请求以在django中将视图呈现给字符串

时间:2011-08-31 15:20:45

标签: python django

问题

我想通过在另一个视图中调用视图(捕获响应并提取呈现的内容)到字符串来呈现任意视图。 问题是我想在呈现该视图期间让虚拟用户“登录”,同时更改请求中的一些其他小事。 我想避免的是完全从头开始构建请求,因为我在父视图中有90%的请求将是相同的。

我想知道就最佳做法而言,我应该如何解决这个问题,以及技术上的问题?

我现在正在考虑这样的事情:(但我不禁觉得这太可怕了,而且必须有更好的方式,我根本想不到它)

  

查看内容...

     

记录当前用户

     

创建/登录虚拟用户

     

以某种方式修改请求

     

将视图渲染为字符串

     

注销虚拟用户

     

重新登录原始用户

     

结束观点...

有什么想法吗?或指向更好方向的指针?

谢谢, dennmat

3 个答案:

答案 0 :(得分:2)

根据您在视图中依赖于从请求中获取信息的程度,最好只创建一个函数来完成所有视图的脏工作,并让您的真实视图传递给值它需要进入这个功能。因此,不是采用请求的视图函数,而是创建另一个需要用户的函数:

def _real_view(user):
    return render_to_response('template.html', {'user' : user})

def view(request):
    # Now both of these are possible...
    response = _real_view(User.objects.get(5))
    response = _real_view(request.user)
    return response

然后,当您想要使用其他用户的视图时,您只需要获取该用户的信息并将其传递到视图中。无需更改当前用户或完全修改请求。

答案 1 :(得分:1)

您实际上不需要记录当前用户,您只需更改计划用于呈现其他视图的HttpRequest对象中的用户。你可以这样做:

from django.contrib.auth.models import User
from django.http import HttpResponse

def view_inside_a_view(request):
    return HttpResponse('hello %s' % request.user)

def view(request):
    # change to dummy user, or whoever
    request.user = User.objects.get(id=1)
    response = view_inside_a_view(request)
    return HttpResponse('rendered view: %s' % response.content)

如果您需要登录虚拟用户,可以使用django.contrib.auth.authenticatedjango.contrib.auth.login来执行此操作。使用login的示例(避免使用虚拟用户密码的必要性):

from django.contrib.auth.models import User
from django.contrib.auth import login, get_backends
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse

@login_required
def view_inside_a_view(request):
    return HttpResponse('hello %s' % request.user)

def view(request):
    # login dummy user
    user = User.objects.get(id=2)
    backend = get_backends()[0]
    user.backend = "%s.%s" % (backend.__module__, backend.__class__.__name__)
    login(request, user)
    # change request's user
    request.user = user
    # get response from view
    response = view_inside_a_view(request)
    return HttpResponse('rendered view: %s' % response.content)

答案 2 :(得分:1)

只需使用测试客户端 - 它不仅有助于测试:

from django.test import Client

c = Client()
# login if necessary
c.login(username='dummy', password='user')
# get the view
response = c.get(reverse('my-view', args=[foo,bar])
html = response.content

自1.6以来,这甚至已经正式记录,但它也适用于旧版本:https://docs.djangoproject.com/en/1.6/topics/testing/tools/#module-django.test.client