如何在使用 django.test 测试用例时从视图中获取对象
How to get a object from a view while using a django.test TestCase
我正在尝试访问将被发送到模板的对象 'wines'。基本上,在这个例子中,我的葡萄酒是以瓶装、玻璃杯或两者兼而有之的方式出售的。我正在进行的第一个测试应该能够在一个名为 'wines' 的对象中检索所有 3 种葡萄酒,该对象被发送到模板。 (create_wine() 是自定义的 Wine.objects.create() 方法)。
如果你注意到了,我正在使用 django.test import TestCase 所以我有一个 self.client 对象可以使用。此外,如果您注意到,我会向您展示我在“(调试)”文本中尝试调试的位置。
我真正想要得到的是预渲染的json。在我看来,视图使用对象呈现 html 来创建它需要的 html 和 returns 。那么我该如何访问这个预渲染对象呢?
问题是我将使用相同的视图来呈现这些葡萄酒对象。如果可能的话,我想使用相同的模板,这意味着将数据发送到视图并重写它,以便它在渲染之前获取正确的葡萄酒。我觉得这没问题。如果这破坏了 django 方法论,我洗耳恭听。
有没有其他方法可以解决这个问题,或者我已经很接近了?
代码
浏览次数
def wine_list(request):
wines = Wine.objects.filter(is_active=True)
return render(request, 'wine/wine_list.html', {'wines': wines})
网址
urlpatterns = [
url(r'^$', 'wine.views.wine_list', name='wine_list'),
url(r'^bottle/$', 'wine.views.wine_list', name='wine_list_bottle'),
url(r'^glass/$', 'wine.views.wine_list', name='wine_list_glass'),
url(r'^([0-9]+)/$', 'wine.views.wine_details', name='wine_detail'),
]
UT
from django.test import TestCase
def test_both_wine_glass_and_bottle_pull_different_objects(self):
# Todo: how to pull object info from view
self.create_wine(container="bottle")
self.create_wine(container="glass")
self.create_wine(container="both")
request = self.client.get("/wine/")
from wine.views import wine_list
result = wine_list(request)
(debug) result
# assert wine/ wine is both glass and bottle
# assert wine/glass/ wine is only both or glass wines
# assert wine/bottle/ wine is only both or bottle wines
self.fail("finish the test")
'result' 在(调试)
result = {HttpResponse} <HttpResponse status_code=200, "text/html; charset=utf-8">
_charset = {NoneType} None
_closable_objects = {list} <class 'list'>: []
_container = {list} <class 'list'>: [b'<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <title>Wine List</title>\n \n <link rel="stylesheet" href="/static/wine/reset.css">\n <link rel="stylesheet" href="/static/wine/menu.css">\n</head>\n<bod
_handler_class = {NoneType} None
_headers = {dict} {'content-type': ('Content-Type', 'text/html; charset=utf-8')}
_reason_phrase = {NoneType} None
charset = {str} 'utf-8'
closed = {bool} False
content = {bytes} b'<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <title>Wine List</title>\n \n <link rel="stylesheet" href="/static/wine/reset.css">\n <link rel="stylesheet" href="/static/wine/menu.css">\n</head>\n<body>\n <header c
cookies = {SimpleCookie}
reason_phrase = {str} 'OK'
status_code = {int} 200
streaming = {bool} False
其他通过单元测试(如果这些有帮助的话)
self.create_wine(container="both")
bottle = Wine.bottle.all()
glass = Wine.glass.all()
both = Wine.objects.all()
self.assertEqual(2, len(bottle))
self.assertEqual(2, len(glass))
self.assertEqual(3, len(both))
def test_both_wine_glass_and_bottle_pull_the_same_template(self):
bottle_list = self.client.get('/wine/bottle/')
glass_list = self.client.get('/wine/glass/')
both_list = self.client.get('/wine/')
self.assertTemplateUsed(both_list, 'wine/wine_list.html')
self.assertTemplateUsed(bottle_list, 'wine/wine_list.html')
self.assertTemplateUsed(glass_list, 'wine/wine_list.html')
简单模板wine_list.html
{% extends 'wine/base.html' %}
{% block content %}
<section id="wine_content">
<div class="cards">
{% for wine in wines %}
<div class="card">
<a href="/wine/{{ wine.id }}">
<h4>{{ wine.name }}</h4>
<p>{{ wine.vintage }}</p>
<p>{{ wine.description}}</p>
</a>
</div>
{% endfor %}
</div>
</section>
{% endblock %}
您误解了测试客户端的工作原理。当您调用 self.client.get("/wine/")
时,它会模拟对 /wine/
的请求,并调用您的 wine_list
视图。您不必手动调用 wine_list
。
client.get()
调用returns一个响应。然后,您可以使用响应进行测试断言,并从 response.context
.
中获取项目
response = self.client.get("/wine/")
self.assertEqual(response.status_code, 200) # check 200 OK response
wines = response.context['wines'] # this is the list of wines you included in the context
# check that wines is as you expected.
for wine in wines:
# All wines should be active
self.assertTrue(wine.is_active)
...
我正在尝试访问将被发送到模板的对象 'wines'。基本上,在这个例子中,我的葡萄酒是以瓶装、玻璃杯或两者兼而有之的方式出售的。我正在进行的第一个测试应该能够在一个名为 'wines' 的对象中检索所有 3 种葡萄酒,该对象被发送到模板。 (create_wine() 是自定义的 Wine.objects.create() 方法)。
如果你注意到了,我正在使用 django.test import TestCase 所以我有一个 self.client 对象可以使用。此外,如果您注意到,我会向您展示我在“(调试)”文本中尝试调试的位置。
我真正想要得到的是预渲染的json。在我看来,视图使用对象呈现 html 来创建它需要的 html 和 returns 。那么我该如何访问这个预渲染对象呢?
问题是我将使用相同的视图来呈现这些葡萄酒对象。如果可能的话,我想使用相同的模板,这意味着将数据发送到视图并重写它,以便它在渲染之前获取正确的葡萄酒。我觉得这没问题。如果这破坏了 django 方法论,我洗耳恭听。
有没有其他方法可以解决这个问题,或者我已经很接近了?
代码
浏览次数
def wine_list(request):
wines = Wine.objects.filter(is_active=True)
return render(request, 'wine/wine_list.html', {'wines': wines})
网址
urlpatterns = [
url(r'^$', 'wine.views.wine_list', name='wine_list'),
url(r'^bottle/$', 'wine.views.wine_list', name='wine_list_bottle'),
url(r'^glass/$', 'wine.views.wine_list', name='wine_list_glass'),
url(r'^([0-9]+)/$', 'wine.views.wine_details', name='wine_detail'),
]
UT
from django.test import TestCase
def test_both_wine_glass_and_bottle_pull_different_objects(self):
# Todo: how to pull object info from view
self.create_wine(container="bottle")
self.create_wine(container="glass")
self.create_wine(container="both")
request = self.client.get("/wine/")
from wine.views import wine_list
result = wine_list(request)
(debug) result
# assert wine/ wine is both glass and bottle
# assert wine/glass/ wine is only both or glass wines
# assert wine/bottle/ wine is only both or bottle wines
self.fail("finish the test")
'result' 在(调试)
result = {HttpResponse} <HttpResponse status_code=200, "text/html; charset=utf-8">
_charset = {NoneType} None
_closable_objects = {list} <class 'list'>: []
_container = {list} <class 'list'>: [b'<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <title>Wine List</title>\n \n <link rel="stylesheet" href="/static/wine/reset.css">\n <link rel="stylesheet" href="/static/wine/menu.css">\n</head>\n<bod
_handler_class = {NoneType} None
_headers = {dict} {'content-type': ('Content-Type', 'text/html; charset=utf-8')}
_reason_phrase = {NoneType} None
charset = {str} 'utf-8'
closed = {bool} False
content = {bytes} b'<!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <title>Wine List</title>\n \n <link rel="stylesheet" href="/static/wine/reset.css">\n <link rel="stylesheet" href="/static/wine/menu.css">\n</head>\n<body>\n <header c
cookies = {SimpleCookie}
reason_phrase = {str} 'OK'
status_code = {int} 200
streaming = {bool} False
其他通过单元测试(如果这些有帮助的话)
self.create_wine(container="both")
bottle = Wine.bottle.all()
glass = Wine.glass.all()
both = Wine.objects.all()
self.assertEqual(2, len(bottle))
self.assertEqual(2, len(glass))
self.assertEqual(3, len(both))
def test_both_wine_glass_and_bottle_pull_the_same_template(self):
bottle_list = self.client.get('/wine/bottle/')
glass_list = self.client.get('/wine/glass/')
both_list = self.client.get('/wine/')
self.assertTemplateUsed(both_list, 'wine/wine_list.html')
self.assertTemplateUsed(bottle_list, 'wine/wine_list.html')
self.assertTemplateUsed(glass_list, 'wine/wine_list.html')
简单模板wine_list.html
{% extends 'wine/base.html' %}
{% block content %}
<section id="wine_content">
<div class="cards">
{% for wine in wines %}
<div class="card">
<a href="/wine/{{ wine.id }}">
<h4>{{ wine.name }}</h4>
<p>{{ wine.vintage }}</p>
<p>{{ wine.description}}</p>
</a>
</div>
{% endfor %}
</div>
</section>
{% endblock %}
您误解了测试客户端的工作原理。当您调用 self.client.get("/wine/")
时,它会模拟对 /wine/
的请求,并调用您的 wine_list
视图。您不必手动调用 wine_list
。
client.get()
调用returns一个响应。然后,您可以使用响应进行测试断言,并从 response.context
.
response = self.client.get("/wine/")
self.assertEqual(response.status_code, 200) # check 200 OK response
wines = response.context['wines'] # this is the list of wines you included in the context
# check that wines is as you expected.
for wine in wines:
# All wines should be active
self.assertTrue(wine.is_active)
...