Search code examples
pythonregexdjangodjango-urlsurl-pattern

Django - 'otherwise' fallback default URLConf in urls.py


I have the following urls.py:

from django.conf import settings
from django.conf.urls import include, url
from django.conf.urls.static import static
from django.contrib import admin
from django.views.generic.base import RedirectView

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^$', 'news_readr.views.home', name='home'),
    url(r'^details/(?P<article_id>[0-9]+)$', 'news_readr.views.details', name='details'),
    url(r'^details/$', 'news_readr.views.details', name='details'),
    url(r'^/$', 'news_readr.views.home', name='home'),
]


if settings.DEBUG:
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

I have two valid URLs in my app:

  1. localhost:8000/
  2. localhost:8000/details/123 #Where 123 can be any number

I want to put a RegEx in there that handles are the other situations and routes those requests back to the 'home' view. But nothing I'm trying seems to work. I tried putting these as the last line in my urlpattern:

url(r'^/$', 'news_readr.views.home', name='home'), #this does nothing
url(r'', 'news_readr.views.home', name='home'), #this redirects fine to my homepage, but breaks all of my media and static paths, and causes my images to not load

Is there a better way or a correct regex I can use to fix this situation?


Solution

  • Showing home page on any request that normally would result in HTTP 404 is not the best practice, it's confusing for people and robots. If you still want to do that, better use HTTP 301 redirect. For that purpose, Django has RedirectView:

    from django.core.urlresolvers import reverse
    from django.views.generic import RedirectView
    
    class RedirectToHome(RedirectView):
    
        def get_redirect_url(self, *args, **kwargs):
            return reverse('home')
    

    To fix your static files problem, simply insert static URLs before your all-catching URL:

    # You don't have to check DEBUG because static() does nothing if DEBUG is False.
    urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
    
    urlpatterns.append(url(r'^.*$', views.RedirectToHome.as_view(), name='redirect_to_home'))