Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a catch all route using `path` or `re_path` so that Django passes all unmatched requests to my index view?

My url patterns look like this:

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

    re_path('.*', IndexView.as_view()),
]

This works but it matches all URLs, including those prefixed with admin and api. I want those URLs to still match, and for any unmatched URLs to render IndexView.

Before 2.0 I used this regex for this purpose. I tried using it in re_path but that didn't work, which is what led me to trying the above.

url(r'^(?P<path>.*)/$', HtmlView.as_view())

Use case is a SPA where I handle 404s client side.

Many thanks in advance.

like image 643
ergusto Avatar asked Jun 28 '18 14:06

ergusto


People also ask

What does re_path do in Django?

re_path is an implementation of the 'old' way of handling urls, which was previously (version <2) done by url from django. conf. urls . See the paragraph in Django 2.0 release notes about this.

What is the difference between path and re_path in Django?

For my understanding is that the path function does not accept regex urls anymore, you need to use the new urls syntax <slug:title> instead of passing a regex to match parameters. The re_path only work with regex formatted urls (The old way we make urls).

Which method is used instead of path () in Django?

url(regex, view, kwargs=None, name=None) This function is an alias to django. urls. re_path() .

Which method is used instead of path () in urls py to pass in regular expressions as routes?

To do so, use re_path() instead of path() . In Python regular expressions, the syntax for named regular expression groups is (?P<name>pattern) , where name is the name of the group and pattern is some pattern to match.


1 Answers

You can use two entries (one for '/', another one for anything else), but using path for both of them, which should be (slightly) more efficient:

urlpatterns = [
    path('', IndexView.as_view(), {'resource': ''}),
    path('<path:resource>', IndexView.as_view())
]

In this case, I'm using <path:resource> because path catches all resource names, inluding that with / in them. But it does not capture the main index resource, /. That's why the first entry. The dictionary as last argument for it is because we need to provide a resource parameter if we want to use the same view than in the second entry.

That view, of course, should have 'resource' as a paremeter:

def as_view(request, resource):
   ...
like image 110
jgbarah Avatar answered Oct 03 '22 15:10

jgbarah