how to “break” from a regex in urlconf

22 views
Skip to first unread message

Matthew Meyer

unread,
Aug 27, 2012, 2:14:59 AM8/27/12
to django...@googlegroups.com

I have the following views:

def tag_page(request, tag):

    products
= Product.objects.filter(tag=tag)

   
return render(request, 'shop/tag_page.html', {'products': products, 'tag': tag})


def product_page(request, slug):

    product
= Product.objects.get(slug=slug)

   
return render(request, 'shop/product_page.html', {'product': product})

along with the following url configurations:

url(r'^(?P<tag>.+)/$', 'tag_page'),
url
(r'^(?P<tag>.+)/(?P<slug>[-\w]+)/$', 'product_page'),

The regex that has "tag" in it allows a url path to grow arbitrarily while sort of circularly redirecting to the tag_page view.

This lets me have the url: /mens/shirts/buttonups/, where all sections (/mens, /mens/shirts, /mens/shirts/buttonups/) of the path direct to the tag_page view, which is desired.

I want to end this behavior at some point however, and direct to a product_page view, which I attempt to accomplish with:

url(r'^(?P<tag>.+)/(?P<slug>[-\w]+)/$', 'product_page'),

When I follow a product_page link:

<a href="{{ product.slug }}">{{ product }}</a>

I am directed to the tag_pag view. Presumably because that slug url matches the tag regex.

So the question: Is there a way I can keep the flexible tag regex redirect behavior but then "break" from it once I reach a product page? One important thing to note is that I want to keep the product page within the built up url scheme like: mens/shirts/buttonups/shirt-product/

Any insight is appreciated, Thanks!

Melvyn Sopacua

unread,
Aug 27, 2012, 7:18:52 AM8/27/12
to django...@googlegroups.com
On 27-8-2012 4:14, Matthew Meyer wrote:

> So the question: Is there a way I can keep the flexible tag regex redirect
> behavior but then "break" from it once I reach a product page? One
> important thing to note is that I want to keep the product page within the
> built up url scheme like: mens/shirts/buttonups/shirt-product/

The first thing to note is that you need to get "redirect" and "break
out" out of your vocabulary. While Django's urlconfs look and walk like
rewrite engines, they are not rewrite engines. The primary difference is
that matches are handled in order and the first match wins, so there is
no "break out" principle.
Since a slug and a tag in your matches consist of identical character
classes there is no way to differentiate between one or the other. The
easy solution and one that is in line with the semantics of URLs is to
drop the trailing slash for the product.
"Back in the day" trailing slashes meant "directory listings" and no
trailing slash referred to "document requests" and this applies to your
scheme also. So your product url becomes:
url(r'^(?P<tag>.+)/(?P<slug>[-\w]+)$', 'product_page'),
--
Melvyn Sopacua

Matthew Meyer

unread,
Aug 27, 2012, 12:30:23 PM8/27/12
to django...@googlegroups.com
Fantastic solution, thank you so much. I will be sure to loose those phrases from my vocab as well :)
Reply all
Reply to author
Forward
0 new messages