How to iterate over all View objects for all routes in django in a unit test?

Viewed 13

For compliance reasons, there is sometimes a need to ensure that all or some views have to have certain attributes or behaviours. I want to add tests to ensure that this is enforced, and more importantly, that it will be enforced against future views added by other devs.

I need to be able to do something like

def test_compliance_thing():
    for all possible views
       assert hasattr(view, 'some_compliance_thing')
1 Answers
from django.urls import get_resolver
def _get_urlpatterns(resolver):
    result = []
    for x in resolver.url_patterns:
        if hasattr(x, 'url_patterns'):
            # x is a resolver
            result += _get_urlpatterns(x)
        result.append(x)
    return result


def get_all_view_classes():
    return (x.callback.view_class for x in _get_urlpatterns(get_resolver()) if hasattr(x.callback, 'view_class'))

Interestingly I found another way of obtaining urlpatterns that I think yields the same result

>>> x1 = set([x.callback.view_class for x in get_resolver().url_patterns if x.callback])
>>> x2 = set([k.view_class for k in get_resolver().reverse_dict.keys() if type(k) != str])
>>> x1 == x2
True

Note that this solution will not cover some edge cases. See https://github.com/django-extensions/django-extensions/blob/main/django_extensions/management/commands/show_urls.py

Related