Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

103
Views
Tests for view names failing since upgrading to Django 4.0

In a Django project I have tests that check that a URL uses a specific class-based view. e.g. I have this view:

from django.views.generic import TemplateView

class HomeView(TemplateView):
    template_name = "home.html"

And this test:

from django.test import TestCase
from django.urls import resolve
from myapp import views

class UrlsTestCase(TestCase):

    def test_home_view(self):
        self.assertEqual(resolve("/").func.__name__, views.HomeView.__name__)

This test passes in Django 3.x but once I try it with Django 4.0 the test fails with:

self.assertEqual(resolve("/").func.__name__, views.HomeView.__name__)
AssertionError: 'view' != 'HomeView'
- view
+ HomeView

Obviously something has changed in Django 4.0 but I can't see anything related in the release notes.

So, what's changed and how can I make this test work again (or how can I test this in a better way)?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

You use .as_view(), it thus does not return a class object, but a function that will handle requests by creating a new HomeView and trigger the corresponding method based on the HTTP method.

You can check if it is a method of the HomeView by checking the .view_class attribute. Furthermore it is probably better to check if the two classes are the same, not the names of these classes:

#                                            ↓ no .__name__  ↓
self.assertEqual(resolve('/').func.view_class, views.HomeView)

I did some research why comparing the __name__s no longer works. Apparently in django-3.0 they used the update_wrapper(…) function which sets the __name__, __qualname__, etc. of one object (in this case the class) to the function. Indeed, in the source code [GitHub], we can see:

@classonlymethod
def as_view(cls, **initkwargs):
    # …
    def view(request, *args, **kwargs):
        # …
    # …

    # take name and docstring from class
    update_wrapper(view, cls, updated=())
    # …

this has been changed in django-4.0 where they also explained in a comment why they do no longer do that [GitHub]:

@classonlymethod
def as_view(cls, **initkwargs):
    # …
    # __name__ and __qualname__ are intentionally left unchanged as
    # view_class should be used to robustly determine the name of the view
    # instead.
    # …
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!