Solving TypeError: view must be a callable or a list/tuple in the case of include() in Django

TypeError: view must be a callable or a list/tuple in the case of include() is an error which occurs in Django because of Django’s rules and limitations.

In this post we will try solving this problem while studying what makes it happen in the first place.

Describing TypeError: view must be a callable or a list/tuple in the case of include()

First of all, let us check out how the message of the error looks like.

                                                                        #
Traceback (most recent call last):
    fn(*args, **kwargs)
...
    raise TypeError('view must be a callable or a list/tuple in the case of include().')
TypeError: view must be a callable or a list/tuple in the case of include().
                                                                       #

The error occurs when you get the views from the url patterns but this does not work in Django 1.10.

Now, the code bellow produces the error above

                                                                       #
from django.conf.urls import include, url
urlpatterns = [
    url(r'^$', 'myapp.views.home'),
    url(r'^contact/$', 'myapp.views.contact'),
    url(r'^login/$', 'django.contrib.auth.views.login'),
                      ]
                                                                       #

Solution 1 : individually import the views in Django

In Django 1.10 and newer versions you need to individually import the views.

You cannot put the views in the url patterns like we used to do before, like in the faulty code bellow

                                                                       #
from django.conf.urls import include, url
urlpatterns = [
    url(r'^$', 'myapp.views.home'),
    url(r'^contact/$', 'myapp.views.contact'),
    url(r'^login/$', 'django.contrib.auth.views.login'),
                      ]
                                                                       #

The code above should be replaced by the following code which includes the fixes

                                                                       #
from django.conf.urls import include, url
from django.contrib.auth.views import login
from myapp.views import home, contact
urlpatterns = [
    url(r'^$', home, name='home'),
    url(r'^contact/$', contact, name='contact'),
    url(r'^login/$', login, name='login'),
]
                                                                       #

Solution 2 : downgrade Django

Another fix, which only works if you do not want to use the solution above is to downgrade from the Django version you have now to Django version 1.9.

Django 1.9 and the earlier versions will solve the issue but downgrading is not exactly the easiest and most pragmatic fix.

Summing-up

This is the end of our article, this is a confusing error but with a small investigation the error could be solved, thank you for reading.

To support us consider donating to our Kofi account above. Keep coding, keep learning and cheers.

If you want to learn more about Python, please check out the Python Documentation : https://docs.python.org/3/