14👍
url patterns are checked in the order you define them
so here:
urlpatterns = [
url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
]
…the first pattern is getting matched (because it does not end with $
so the extra segment is just ignored)
…and that pattern only passes a single keyword arg
Generally it is a bad idea to have multiple url patterns pointing to the same view. If possible you should try and make a single regex (eg using optional groups) which handles the various cases of the url for a particular view. It’s more explicit that way.
On the other hand, simply reversing the order of your patterns to put the more explicit one first would also work and be correct (this is the Django rule of urlpatterns!)
urlpatterns = [
url(r'(?P<post_id>[^/]+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
url(r'(?P<post_id>[^/]+)', GenreDetail.as_view(), name = 'post'),
]
As @ozgur mentions you also need to tell the view to use post_id
instead of pk
by setting pk_url_kwarg
11👍
If you want to fetch details using either post_id or slug then your urls should be like this
url(r'post/(?P<post_id>\d+)/$', GenreDetail.as_view(), name = 'post_detail'),
url(r'post/(?P<slug>[-\w]+)/$', GenreDetail.as_view(), name = 'post_detail_slug'),
And your view should be like this
from django.views.generic import DetailView
class GenreDetail(DetailView):
model = Post
template_name = "post.html"
pk_url_kwarg = "post_id"
slug_url_kwarg = 'slug'
query_pk_and_slug = True
For more details please read the docs.
- Django: Natural Sort QuerySet
- Can I cut out the string in the Django template?
- Django CharField blank vs default empty
- "Error: That IP address can't be assigned-to" when running app
4👍
The problem is that you have to tell DetailView
that it should use post_id
keyword in the URL instead of default ones pk
or slug
in order to get the object that will be displayed.
This can be done by setting pk_url_kwarg
attribute:
(Your url definition is also wrong, always end your url definitions with $
. Below is the corrected version)
url(r'(?P<post_id>\d+)$', GenreDetail.as_view(), name = 'post'),
url(r'(?P<post_id>\d+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
The following urls will match given the url patterns above:
- /2
- /2/memoirs-of-a-geisha-by-arthur-golden
from django.views.generic import DetailView
class GenreDetail(DetailView):
model = Post
template_name = "post.html"
pk_url_kwarg = "post_id"
Alternatively, you can just change post_id
to pk
in your url so you don’t have to touch anything in your view:
url(r'(?P<pk>\d+)$', GenreDetail.as_view(), name = 'post'),
url(r'(?P<pk>\d+)/(?P<slug>[-\w]+)$', GenreDetail.as_view()),
- Django: logging only for my project's apps
- How do I serve media files in a local Django environment?
- Django Boolean Queryset Filter Not Working
0👍
Using path:
from django.urls import path
from . import views
urlpatterns = [
path('<pk>/', views.GenreDetail.as_view(), name="post")]
For slug
:
path('<slug:slug>/', views.GenreDetail.as_view(), name="post")
- Render an xml to a view
- How to add anchor to django url in template
- Creating an entire web application using django admin
- Good tool for automatic setup and deployment of Django projects