Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python Django Basics Test Time View Tests

Adam Cameron
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Adam Cameron
Python Web Development Techdegree Graduate 16,731 Points

Django saying 'course' isn't a registered namespace upon running tests.

No clue what's going on here - my namespace in learning_site/urls.py is clearly "courses", the local URL name in courses/urls.py is "list", and the URL I'm pointing to in the reverse() function is 'courses:list', but Django says 'course is not a registered namespace.` What on earth? "Course" isn't the name of my namespace. It's "courses". What the hell is going on here?

Traceback:

ERROR: test_course_list_view (courses.tests.CourseViewsTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/urls/base.py", line 77, in reverse
    extra, resolver = resolver.namespace_dict[ns]
KeyError: 'course'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/learning_site/courses/tests.py", line 57, in test_course_list_view
    resp = self.client.get(reverse('courses:list'))
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/test/client.py", line 536, in get
    **extra)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/test/client.py", line 340, in get
    return self.generic('GET', path, secure=secure, **r)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/test/client.py", line 416, in generic
    return self.request(**r)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/test/client.py", line 501, in request
    six.reraise(*exc_info)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/utils/six.py", line 686, in reraise
    raise value
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/learning_site/courses/views.py", line 6, in course_list
    return render(request, 'courses/course_list.html', {'courses': courses})
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/shortcuts.py", line 30, in render
    content = loader.render_to_string(template_name, context, request, using=using)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/template/loader.py", line 68, in render_to_string
    return template.render(context, request)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/template/backends/django.py", line 66, in render
    return self.template.render(context)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/template/base.py", line 207, in render
    return self._render(context)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/test/utils.py", line 107, in instrumented_test_render
    return self.nodelist.render(context)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/template/loader_tags.py", line 177, in render
    return compiled_parent._render(context)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/test/utils.py", line 107, in instrumented_test_render
    return self.nodelist.render(context)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/template/base.py", line 990, in render
    bit = node.render_annotated(context)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/template/base.py", line 957, in render_annotated
    return self.render(context)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/template/defaulttags.py", line 458, in render
    url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)
  File "/Users/Adam/Desktop/Treehouse/DjangoBasics/djangobasics/lib/python3.5/site-packages/django/urls/base.py", line 87, in reverse
    raise NoReverseMatch("%s is not a registered namespace" % key)
django.urls.exceptions.NoReverseMatch: 'course' is not a registered namespace

learning_site/urls.py

from django.conf.urls import url
from django.contrib import admin
from . import views
from django.conf.urls import include
from django.contrib.staticfiles.urls import staticfiles_urlpatterns

urlpatterns = [
    url(r'^courses/', include('courses.urls', namespace='courses')),
    url(r'^admin/', admin.site.urls),
    url(r'^$', views.home, name="home"),
]

urlpatterns += staticfiles_urlpatterns()

courses/urls.py

urlpatterns = [
    url(r'^$', views.course_list, name='list'),
    url(r'(?P<course_pk>\d+)/(?P<step_pk>\d+)/$', views.step_detail, name="step"),
    url(r'(?P<pk>\d+)/$', views.course_detail, name="detail"),
]

tests.py

class CourseViewsTests(TestCase):
    def setUp(self):
        self.course = Course.objects.create(
            title="Python Testing",
            description="Sample description"
        )
        self.course2 = Course.objects.create(
            title="New Course",
            description="New course description"
        )
        self.step = Step.objects.create(
            title="Intro to Doctests",
            description="Learn to write tests in your docstrings",
            course=self.course
        )

    def test_course_list_view(self):
        resp = self.client.get(reverse('courses:list'))
        self.assertEqual(resp.status_code, 200)
        self.assertIn(self.course, resp.context['courses'])
        self.assertIn(self.course2, resp.context['courses'])
Adam Cameron
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Adam Cameron
Python Web Development Techdegree Graduate 16,731 Points

tests.py will look a bit different from what Kenneth was demonstrating if you looked at my repo in the last few minutes - I was trying to make something I read in the docs work:

https://docs.djangoproject.com/en/1.11/topics/testing/tools/

But I just put everything back the way it was.

Chris Freeman
Chris Freeman
Treehouse Moderator 67,989 Points

This Stack Overflow answer might solve the issue.

Downloading and debuging from GitHub is currently beyond my volunteer support scope due to my available time, sorry.

Adam Cameron
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Adam Cameron
Python Web Development Techdegree Graduate 16,731 Points

Well the problem is that my exact code works if I copy and paste it into a workspace. So it's either an issue with the Django version or something on my local machine. Thanks though.