I'm trying to configure my app's routing such that the appropriate view page is looked up via the pk, and it returns a redirect with the proper url that has the correct slug following.
For example, I have the model Post
with the title
and slug
fields. Let's say I have a Post
object with the pk 1
and slug hello-world
. What I would like to happen is that you will be redirected to /post/1/hello-world/
, whether I navigate to:
/post/1/
/post/1/hello-world/
, or
/post/1/wrong-slug/
The reason why I would like to do this is so that if I happen to update this post's slug to, say, hello-world-revised
, going to /post/1/hello-world/
will (a) still return the correct view, and (b) redirect to the updated/correct url (aka /post/1/hello-world-revised/
).
I have this in my app's urls.py
:
urlpatterns = patterns('',
...
url(r'^(?P<post_id>\d+)(?:/(?P<slug>[\w\d-]+))?/$', views.post, name='blog-post'),
)
And in views.py
:
def post(request, post_id, slug):
post = get_object_or_404(Post, pk=post_id)
return render(request, 'blog/post.html', {'post': post})
This gets me (a) above (retrieving the correct view), but not (b). To try and achieve (b), I have tried:
Performing a redirect in my post view:
def post(request, post_id, slug):
post = get_object_or_404(Post, pk=post_id)
return redirect('blog-post', post.id, post.slug)
But when I navigate to any post, I get the "This webpage has a redirect loop" error.
Overriding the get_absolute_url
method on my Post
model (following the pattern described in this question):
class Post(models.Model):
...
@models.permalink
def get_absolute_url(self):
kwargs = {
'post_id': str(self.id),
'slug': self.slug,
)
return ('blog-post', (), kwargs)
But that didn't have any effect; the correct view returned, but the URL remained as whatever you had typed in initially.
Does anyone know how to get this working?