Maksim Kevin
Maksim Kevin

Reputation: 71

Taking as a parameter but not using in view

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

Answers (2)

thebjorn
thebjorn

Reputation: 27311

You can use a non-capturing group:

url(r'^post/(?P<post_id>\d+)/(?:[\w|\W]+)/$', views.detail, name="detail"),   

Upvotes: 1

Kevin Brown-Silva
Kevin Brown-Silva

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

Related Questions