Django: django.test TestCase self.assertTemplateUsed

#python #django #python-2.7 #django-templates #django-testing

#python #django #python-2.7 #django-шаблоны #django-тестирование

Вопрос:

Работаю над веб-приложением Hello.

Пожалуйста, помогите с TestCase: test_edit_thing .

Вот сведения об ошибке:

Ошибка в случае ‘/things/django-book /edit/’:

 # AssertionError: No templates used to render the response
response = self.client.get('/things/django-book/edit/')
self.assertTemplateUsed(response, 'things/edit_thing.html')
  

Ошибка в случае ‘/things/django-book /’:

 # AssertionError: Template 'things/edit_thing.html' was not a template used to render the response. Actual template(s) used: things/thing_detail.html, base.html
response = self.client.get('/things/django-book/')
self.assertTemplateUsed(response, 'things/edit_thing.html')
  

Фрагмент кода:

 from django.contrib.auth.models import AnonymousUser, User
from django.test import TestCase, RequestFactory

from collection.models import Thing
from .views import *

class SimpleTest(TestCase):
    def setUp(self):
        # Every test needs access to the request factory.
        self.factory = RequestFactory()
        self.user = User.objects.create_user(username='Foo', password='barbaz')        
        self.thing = Thing.objects.create(name="Django Book",
                                     description="Learn how to build your first Django web app.",
                                     slug="django-book",
                                     user=self.user)

    def test_index(self):
        request = self.factory.get('/index/')
        response = index(request)
        print(response.status_code)
        self.assertEqual(response.status_code, 200)        
        response = self.client.get('/')
        self.assertTemplateUsed(response, 'base.html')

    def test_thing_detail(self):
        django_book = Thing.objects.get(name="Django Book")        
        request = self.factory.get('/things/django-book/')
        response = thing_detail(request, django_book.slug)
        print(response.status_code) 
        self.assertEqual(response.status_code, 200)
        response = self.client.get('/things/django-book/')
        self.assertTemplateUsed(response, 'things/thing_detail.html')

    def test_edit_thing(self):
        django_book = Thing.objects.get(name="Django Book")
        request = self.factory.get('/things/django-book/edit/')
        request.user = django_book.user
        response = edit_thing(request, django_book.slug)
        print(response.status_code) 
        self.assertEqual(response.status_code, 200)

        # AssertionError: No templates used to render the response
        #response = self.client.get('/things/django-book/edit/')

        # AssertionError: Template 'things/edit_thing.html' was not a template used to render the response. Actual template(s) used: things/thing_detail.html, base.html
        #response = self.client.get('/things/django-book/')
        #self.assertTemplateUsed(response, 'things/edit_thing.html')

        # Right?
        response = self.client.get('/things/django-book/')        
        self.assertTemplateUsed(response, 'things/thing_detail.html')
  

views.py

 from django.contrib.auth.decorators import login_required
from django.http import Http404
from django.shortcuts import render, redirect
from django.template.defaultfilters import slugify

from collection.forms import ThingForm
from collection.models import Thing


def index(request):
    things = Thing.objects.all()
    return render(request, 'index.html', {
        'things': things,
    })


def thing_detail(request, slug):
    # grab the object...
    thing = Thing.objects.get(slug=slug)

    # and pass to the template
    return render(request, 'things/thing_detail.html', {
        'thing': thing,
    })


@login_required
def edit_thing(request, slug):
    # grab the object...
    thing = Thing.objects.get(slug=slug)

    # grab the current logged in user and make sure they're the owner of the thing
    if thing.user != request.user:
        raise Http404

    # set the form we're using...
    form_class = ThingForm

    # if we're coming to this view from a submitted form,  
    if request.method == 'POST':
        # grab the data from the submitted form
        form = form_class(data=request.POST, instance=thing)

        if form.is_valid():
            # save the new data
            form.save()
            return redirect('thing_detail', slug=thing.slug)

    # otherwise just create the form
    else:
        form = form_class(instance=thing)

    # and render the template
    return render(request, 'things/edit_thing.html', {
        'thing': thing,
        'form': form,
    })


def create_thing(request):
    form_class = ThingForm

    # if we're coming from a submitted form, do this
    if request.method == 'POST':
        # grab the data from the submitted form and apply to the form
        form = form_class(request.POST)

        if form.is_valid():
            # create an instance but do not save yet
            thing = form.save(commit=False)

            # set the additional details
            thing.user = request.user
            thing.slug = slugify(thing.name)

            # save the object
            thing.save()

            # redirect to our newly created thing
            return redirect('thing_detail', slug=thing.slug)

    # otherwise just create the form
    else:
        form = form_class()

    return render(request, 'things/create_thing.html', {
        'form': form,
    })


def browse_by_name(request, initial=None):
    if initial:
        things = Thing.objects.filter(
             name__istartswith=initial).order_by('name')
    else:
        things = Thing.objects.all().order_by('name')

    return render(request, 'search/search.html', {
        'things': things,
        'initial': initial,
    })
  

Спасибо

Ответ №1:

Итак, проблема, с которой вы столкнулись, заключается в том, что ваш пользователь не был аутентифицирован, и если пользователь не совпадает с пользователем того, что вы вызываете Http404

Это на ваш edit_thing взгляд

 if thing.user != request.user:
    raise Http404
  

Итак, вам нужно было пройти проверку подлинности. И это можно было бы сделать с помощью login

 def test_edit_thing(self):
    django_book = Thing.objects.get(name="Django Book")
    request = self.factory.get('/things/django-book/edit/')
    request.user = django_book.user
    response = edit_thing(request, django_book.slug)
    print(response.status_code)
    self.assertEqual(response.status_code, 200)
    self.client.login(username='Foo', password='barbaz')
    response = self.client.get('/things/django-book/edit/')        
    self.assertTemplateUsed(response, 'things/edit_thing.html')