【问题标题】:Python, Django, Tutorial, Testing Detail View, ErrorPython,Django,教程,测试详细信息视图,错误
【发布时间】:2016-03-03 09:02:50
【问题描述】:

我正在学习 Django 教程,但在教程 5 >“测试详细视图”中偶然发现了错误

当我跑步时:

python manage.py test polls

在终端中,我收到了这条消息:

Creating test database for alias 'default'...
.F.......
======================================================================
FAIL: test_detail_view_with_a_past_question (polls.tests.QuestionIndexDetailTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/theoford/Documents/python/04_django_intro/mysite/polls/tests.py", line 115, in test_detail_view_with_a_past_question
    status_code=200)
  File "/Library/Python/2.7/site-packages/django/test/testcases.py", line 398, in assertContains
    msg_prefix + "Couldn't find %s in response" % text_repr)
AssertionError: Couldn't find 'Past Question.' in response

----------------------------------------------------------------------
Ran 9 tests in 0.030s

FAILED (failures=1)
Destroying test database for alias 'default'...

这是我在 tests.py 中与“用过去的问题测试详细视图”相关的代码(它是后者的函数)。

class QuestionIndexDetailTests(TestCase):
    def test_detail_view_with_a_future_question(self):
        """
        The detail view of a question with a pub_date in the future should
        return a 404 not found.
        """
        future_question = create_question(question_text='Future question.',
                                          days=5)
        response = self.client.get(reverse('polls:detail',
                                   args=(future_question.id,)))
        self.assertEqual(response.status_code, 404)

    def test_detail_view_with_a_past_question(self):
        """
        The detail view of a question with a pub_date in the past should
        display the question's text.
        """
        past_question = create_question(question_text='Past Question.',
                                        days=-5)
        response = self.client.get(reverse('polls:detail',
                                   args=(past_question.id,)))
        self.assertContains(response, past_question.question_text,
                            status_code=200)

我是 * 社区的新手,因此如果此问题的格式和措辞不正确、不完整或不恰当,我深表歉意,但我们将不胜感激任何有助于解决此问题的帮助。

views.py:

from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.views import generic
from django.utils import timezone 

from .models import Choice, Question


class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        """Return the last five published questions (not including those published in the future)."""
        return Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[:5]

class DetailView(generic.DetailView):
    model = Question 
    template_name = 'polls/detail.html'

    def get_queryset(self):
        """
        Excludes any questions that aren't published yet.
        """
        return Question.objects.filter(pub_date__lte=timezone.now())

class ResultsView(generic.DetailView):
    model = Question 
    template_name = 'polls/results.html'

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        selected_choice.votes += 1
        selected_choice.save()
        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('polls:results', args=(question.id,)))

【问题讨论】:

  • 你能显示视图吗?问题可能就在那里。
  • 当然 - 刚刚将其添加到问题中
  • 调试它... 在调用test_detail_view_with_a_past_question() 之前放置import pdb;pdb.set_trace() 它将暂停测试并为您提供一个shell 来检查您的代码... 在那个shell 中Question.objects.all() 检查日期。 ..您甚至可以使用n“逐步”或使用s“步入”
  • 你能发布你的urls.py吗?

标签: python django django-testing


【解决方案1】:

您想检查“过去的问题”。位于response.content,而不是response。将test_detail_view_with_a_past_question的最后一行更改为:

self.assertContains(response.content, past_question.question_text,
                        status_code=200)

【讨论】:

    【解决方案2】:

    在我的案例中,测试用例通过了两种方式:

    1. 通过将属性 pk_url_kwargs 添加到 views.py 中的 DetailView 中,其值为 'question_id'

      pk_url_kwargs = 'question_id'

    1. 通过将 urls.py 中的“question_id”更改为“pk”

      path('/', views.DetailView.as_view(), name='detail'),

    原因:

    据我了解,通用 DetailView 默认根据名为 'pk' 或 'slug' 的参数查找对象——(选择一个主键等于名为 'pk' 的变量的值的对象) ,但在 urls.py 中的教程中,额外的整数参数被命名为“question_id”,因此我们需要更改 views.py 中的 pk_url_kwargs 或 urls.py 中的参数名称。

    【讨论】:

      最近更新 更多