Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用Django测试客户端测试轮询应用程序_Python_Django - Fatal编程技术网

Python 使用Django测试客户端测试轮询应用程序

Python 使用Django测试客户端测试轮询应用程序,python,django,Python,Django,我正在尝试使用Django测试客户端测试民意测验应用程序。在这个测试中,我创建了一个POST请求,模拟投票,然后检查响应的状态代码(以检查我是否已被重定向),并验证投票数是否增加。因此,从我所读到的内容来看,我的tests.py结果如下: from django.test import Client from django.test import TestCase from mysite.polls.models import Question, Choice class PollTest(T

我正在尝试使用Django测试客户端测试民意测验应用程序。在这个测试中,我创建了一个POST请求,模拟投票,然后检查响应的状态代码(以检查我是否已被重定向),并验证投票数是否增加。因此,从我所读到的内容来看,我的
tests.py
结果如下:

from django.test import Client
from django.test import TestCase
from mysite.polls.models import Question, Choice

class PollTest(TestCase):

    def test_voting(self):
        client = Client()
        # Perform a vote on the poll by mocking a POST request.
        response = client.post('/polls/1/vote/', {'choice': '1',})
        # In the vote view we redirect the user, so check the
        # response status code is 302.
        self.assertEqual(response.status_code, 302)
        # Get the choice and check there is now one vote.
        choice = Choice.objects.get(pk=1)
        self.assertEqual(choice.votes, 1)
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,)))
from django.conf.urls import url
from . import views

app_name = 'polls'
urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
   ]
views.py的投票部分如下所示:

from django.test import Client
from django.test import TestCase
from mysite.polls.models import Question, Choice

class PollTest(TestCase):

    def test_voting(self):
        client = Client()
        # Perform a vote on the poll by mocking a POST request.
        response = client.post('/polls/1/vote/', {'choice': '1',})
        # In the vote view we redirect the user, so check the
        # response status code is 302.
        self.assertEqual(response.status_code, 302)
        # Get the choice and check there is now one vote.
        choice = Choice.objects.get(pk=1)
        self.assertEqual(choice.votes, 1)
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,)))
from django.conf.urls import url
from . import views

app_name = 'polls'
urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
   ]
我的
url.py
如下所示:

from django.test import Client
from django.test import TestCase
from mysite.polls.models import Question, Choice

class PollTest(TestCase):

    def test_voting(self):
        client = Client()
        # Perform a vote on the poll by mocking a POST request.
        response = client.post('/polls/1/vote/', {'choice': '1',})
        # In the vote view we redirect the user, so check the
        # response status code is 302.
        self.assertEqual(response.status_code, 302)
        # Get the choice and check there is now one vote.
        choice = Choice.objects.get(pk=1)
        self.assertEqual(choice.votes, 1)
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,)))
from django.conf.urls import url
from . import views

app_name = 'polls'
urlpatterns = [
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>[0-9]+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<pk>[0-9]+)/results/$', views.ResultsView.as_view(), name='results'),
    url(r'^(?P<question_id>[0-9]+)/vote/$', views.vote, name='vote'),
   ]
从django.conf.url导入url
从…起导入视图
应用程序名称='polls'
URL模式=[
url(r'^$',views.IndexView.as_view(),name='index'),
url(r'^(?P[0-9]+)/$',views.DetailView.as_view(),name='detail'),
url(r'^(?P[0-9]+)/results/$',views.ResultsView.as_view(),name='results'),
url(r'^(?P[0-9]+)/vote/$',views.vote,name='vote'),
]

运行
python manage.py test
后,我遇到的第一个问题是,我必须将响应状态代码更改为405,而它应该是302,因为在选择投票并单击投票按钮后,我会被重定向到
/polls/1/results
。此外,投票实际上没有被注册,因为在更改响应状态代码后,为了查看投票是否至少增加了,我得到一个错误,即1是错误的,应该将其更改为0,这意味着投票过程也没有运行。

添加以下装饰程序以允许POST:

from django.views.decorators.http import require_http_methods

@require_http_methods(["POST"])
def vote(request, poll_id):  # this is your method from above
    p = get_object_or_404(Poll, pk=question_id)
    try:
        ...
否则,此视图默认处理
GET
方法。同时,您确实希望
vote()
仅限于
POST
调用,因为它正在修改您的数据


在测试中,使用
response=client.post(…,follow=True)
跟踪重定向并测试最终结果。

您不应该得到405-这意味着“不允许使用方法”。我猜是错误的观点在处理这个请求。请显示您的
轮询/url.py
。注意,您不需要
client=client()
。当使用Django
TestCase
时,只需使用
self.client
。我用
views.py
编辑了我的文章。我猜问题出在URL上,而不是视图上。看起来你是在遵循一个非常旧的教程版本-很长时间以来模型一直是
Question
而不是
Poll
。在本例中,这可能不是问题所在,但将来可能会遇到其他问题。请确保您使用的是最新的Django发行版(目前为1.10或1.8长期支持),并按照正确的教程进行操作,因为我不知道应该在哪里添加装饰器以及装饰器的真正用途是什么?最好使用
@require\u http\u方法([“POST”])
,但这并不能解释当前的问题。不注册
POST
肯定是405错误和数据库中缺少条目的原因。