Reputation: 71
Hi I have a url pattern like this:
url(r'^post/(?P<post_id>\d+)/(?P<post_slug>[\w|\W]+)/$', views.detail, name="detail"),
But I dont use post_slug in my view. There is no problem when someone enters the url like this:
127.0.0.1:8000/post/5/my-first-post/
There is also no problem when someone enters the url like this:
127.0.0.1:8000/post/5/mydflgkdfgld/
How can I handle it? I want both id(for quering) and slug(for beatiful urls).
Thank you for your comments.First state of my view is like this:
def detail(request, post_id, post_slug):
post = get_object_or_404(Post, is_pub=True, pk=post_id)
return render(request, 'blog/index.html', {'post': post})
But I want to make my query with only post_id. But in my new view I used post_slug like this:
def detail(request, post_id, post_slug):
post = get_object_or_404(Post, is_pub=True, pk=post_id)
if post.slug == post_slug:
return render(request, 'blog/index.html', {'post': post})
else:
return HttpResponseRedirect(reverse('blog:detail', args=[post_id, post.slug]))
But I dont know is it ok or not?
Upvotes: 0
Views: 61
Reputation: 27311
You can use a non-capturing group:
url(r'^post/(?P<post_id>\d+)/(?:[\w|\W]+)/$', views.detail, name="detail"),
Upvotes: 1
Reputation: 41671
In your detail
view, you can either add the incoming slug
parameter or just catch **kwargs
as your last argument.
def detail(request, id, slug=''):
# slug might be passed in, but you don't need to worry about it
pass
You can't just omit the slug
parameter, as Django will pass it to the view, even though you don't actually need it. This is because you have a capture group set up for it ((?P<slug>)
in your pattern).
You might be able to just omit the capture group to prevent having the argument passed.
url(r'^post/(?P<post_id>\d+)/[\w|\W]+/$', views.detail, name="detail"),
Which should prevent it from being passed to your view. This is because you aren't telling Django to capture it (No parentheses) and even further, you aren't giving it a name (the ?P<name>
part).
The other option is to use multiple url patterns, to capture the different possibilities (including the optional slug). This doesn't appear to be what you are asking for, but it would handle the case where the slug was not actually passed into the view.
http://localhost:8000/post/5/
Though it's up to you if you want to support that case.
Upvotes: 0