Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django routing - The empty path didn't match any of these

Tags:

django

routing

Very basic question and I was surprised I wasn't able to find an answer. I'm just starting looking at django and did an out-of-box intallation. Created a project and created an app. The default content of urls.py is very simple:

urlpatterns = [
    path('admin/', admin.site.urls),
]

And if I open the django site home page, I get the content with a rocket picture. However, like I said, I have created another app in the project, let's say called 'bboard'. And I have created a simple 'hello world' function in bboard/views.py

def index(request):
    return HttpResponse('Hello world')

to enable it for access through browser, I have modified the original urls.py file in the following way:

from bboard.views import index
urlpatterns = [
    path('admin/', admin.site.urls),
    path('bboard/', index),
]

This way I can access localhost:port/admin and localhost:port/bboard URLs, but if I try to open the home page with localhost:port now, I get Page not found error.

Using the URLconf defined in samplesite.urls, Django tried these URL patterns, in this order: admin/ bboard/ The empty path didn't match any of these.

if I comment out the second item in urlpatterns list, everything works. So why does the additional pattern impact this and what needs to be done to fix it?

like image 558
user3751086 Avatar asked Aug 21 '19 17:08

user3751086


2 Answers

Before you add your own routes Django will serve the default home page at the '/' url. After you add your own route config, django no longer serves up its default sample home page.

From the django's django/views/debug.py:

def technical_404_response(request, exception):
    """Create a technical 404 error response. `exception` is the Http404."""
    try:
        error_url = exception.args[0]['path']
    except (IndexError, TypeError, KeyError):
        error_url = request.path_info[1:]  # Trim leading slash

    try:
        tried = exception.args[0]['tried']
    except (IndexError, TypeError, KeyError):
        tried = []
    else:
        if (not tried or (                  # empty URLconf
            request.path == '/' and
            len(tried) == 1 and             # default URLconf
            len(tried[0]) == 1 and
            getattr(tried[0][0], 'app_name', '') == getattr(tried[0][0], 'namespace', '') == 'admin'
        )):
            return default_urlconf(request)

Note the final else block that returns a default_urlconf if the only url path included is the admin path and the requested url is /. This default_urlconf is the sample Rocket page you mentioned. As soon as you add any of your own routes the if statement in the else block will be false so the default_urlconf is not returned and instead falls through to the normal 404 handler.

Here's the default_urlconf

def default_urlconf(request):
    """Create an empty URLconf 404 error response."""
    with Path(CURRENT_DIR, 'templates', 'default_urlconf.html').open() as fh:
        t = DEBUG_ENGINE.from_string(fh.read())
    c = Context({
        'version': get_docs_version(),
    })

    return HttpResponse(t.render(c), content_type='text/html')
like image 96
azundo Avatar answered Sep 19 '22 22:09

azundo


You need to add an empty url in root urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('bboard.urls'))
]
like image 28
shafik Avatar answered Sep 20 '22 22:09

shafik