Django - how can I get permalink to work with "throwaway" slug

django, django-urls, permalinks, python

Solution

One thing to check for, because I also ran into this problem:

(?P<name_slug>\w+)

Is slugify adding hyphens anywhere? If so the regex won't match, hypens are a non-word character. To fix use `[\w-]+` or similar.

Problem

I'm trying to add slugs to the url in my django app, much like SO does. Currently, I have pages that work just fine with a url like this: ``` http://example.com/foo/123/ ``` I'd like to add 'slugified' urls like so: ``` http://example.com/foo/123/foo-name-here ``` I can get it to work just fine, by simply modifying the urlconf and adding a throwaway value to the view function: ``` #urls.py ulpatterns = patterns('project.app.views', url(r'^foo/(?P<foo_id>\d+)/(?P<name_slug>\w+)/$', 'foo_detail', name='foo_detail'), ) #views.py: def foo_detail(request, foo_id, name_slug): # stuff here, name slug is just discarded ``` Visting the url with the slug works just fine. However, my problem is when I am using `@models.permalink`. For my `Foo` model, I used to have the following, which worked just fine: ``` @models.permalink def get_absolute_url(self): return ('foo_detail', [str(self.id),]) ``` However, after my change, whenever I call `{{ foo.get_absolute_url }}` in my templates, the result is always an empty string. I have tried the following two replacements for `get_absolute_url`, neither of which is working: ``` from django.template.defaultfilters import slugify # attempt 1 @models.permalink def get_absolute_url(self): return ('foo_detail', [str(self.id), slugify(self.name)]) # attempt 2 @models.permalink def get_absolute_url(self): return ('foo_detail', (), { 'foo_id': str(self.id), 'name_slug': slugify(self.name), }) ``` Note that if I add a `print slugify(self.name)` before returning, the slugified name is showing up in the console just fine. When invoking `{{ foo.get_absolute_url }}` in my templates, the result is always an empty string, and I don't get any errors. I know I could replace the method with `return '/foo/%s/%s' % (str(self.id), slugify(self.name))`, but I'm trying to get the permalink working so that my URL is only defined in one place. What am I doing wrong?

Original source