order of matching regex in named group urls in django

430 Views Asked by At

I'm making a blogging website with django. I'm making use of slug to identify a particular article. I'm making these blogs for 3 different fields namely sketches, cakes, and rangolis. But the problem here is, the regex of slug for urls of these three is coming to be the same. I've also named these urls for the ease but somehow can't control the order of matching the three. It is working for the named group regex of the url which is written first in the url file. I'm providing the necessary files below. My main website name is 'website' and the app name is'art'. For the order of named group urls given below the error is 'Rangoli matching query does not exist'. So only the first named group url is working. Can anyone help me resolve this. Thanks in advance!

art/urls.py

url(r'list_sketches.html$', views.sketches_list, name='sketches_list'),

url(r'list_rangolis.html$', views.rangolis_list, name='rangolis_list'),

url(r'list_cakes.html$', views.cakes_list, name='cakes_list'),

url(r'^(?P<slug>[\w-]+)/$', views.rangolis_detail, name='rangolis_detail'),

url(r'^(?P<slug>[\w-]+)/$', views.sketches_detail, name='sketches_detail'),

url(r'^(?P<slug>[\w-]+)/$', views.cakes_detail, name='cakes_detail'),

art/views.py

def sketches_list(request):

    sketches = Sketch.objects.all().order_by('-date') 
    return render(request, 'art/list_sketches.html', {'sketches':sketches}) 

def sketches_detail(request, slug):

    sketch = Sketch.objects.get(slug=slug)
    return render(request, 'art/detail_sketches.html', {'each':sketch})

list_sketches.html

{% extends "me/base_layout.html" %}

{% block content %}

    {% for each in sketches %}

        <h1><a href="{% url 'art:sketches_detail' slug=each.slug %}"> {{ each.title }}</a> </h1>
        <p>{{ each.date}}</p>
        <p>{{ each.snippet }}</p>
    {% endfor %}

{% endblock %}

detail_sketches.html

{% extends "me/base_layout.html" %}

{% block content %}


    <h1> {{ each.title }} </h1>
    <p>{{ each.date}}</p>
    <img src="{{ each.sketch.url}}"/>
    <p>{{ each.body }}</p>
{% endblock %}
1

There are 1 best solutions below

2
Alasdair On BEST ANSWER

You can't use the same regex r'^(?P<slug>[\w-]+)/$' multiple times. The Django URL resolver stops as soon as it makes a match, so it will always call the rangolis_detail view.

One option is to change the regexes so that they don't clash, for example:

url(r'^rangolis/(?P<slug>[\w-]+)/$', views.rangolis_detail, name='rangolis_detail'),
url(r'^sketches/(?P<slug>[\w-]+)/$', views.sketches_detail, name='sketches_detail'),
url(r'^cakes/(?P<slug>[\w-]+)/$', views.cakes_detail, name='cakes_detail'),

Another option is to have a single detail URL pattern and view.

url(r'^(?P<slug>[\w-]+)/$', views.detail, name='detail'),

Then your detail view must fetch the correct object from the database and render the appropriate template.