I would like to support the above views in a single view in url ...in my search I came across this post which is no longer supported and all the tutorials i've found have been outdated, which demonstrate how to accomplish the task in django 1.8.3.
In 'products/views.py' I have created a views for products and details. ProductListView will display all products, while ProductDetailView will display a single product detail (title, description, price etc).
products/views.py
class ProductListView(ListView):
queryset = Product.objects.all()
template_name = "products/list.html"
class ProductDetailView(DetailView):
queryset = Product.objects.all()
template_name = "products/detail.html"
products/urls.py include path to the views for ProductListView and ProductDetailView. ProductListView appears to be correct. ProductDetailView is incorrect! I'm getting the following warnings:
WARNINGS: ?: (2_0.W001) Your URL pattern '^products/(?P\d+)/$' [name='details'] has a route that contains '(?P<', begins with a '^', or ends with a '$'. This was likely an oversight when migrating to django.urls.path().
ecommerce.py/urls.py is where i've included products and details urls
ecommerce/urls.py:
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
from .views import home, about, contact
urlpatterns = [
path('admin/', admin.site.urls),
path('', home, name='home'),
path('about/', about, name='about'),
path('products/', include('products.urls'), name='products'),
path('products/', include('products.urls'), name='details'),
path('contact/', contact, name='contact'),
path('account/', include('allauth.urls'), name='login'),
path('register/', include('allauth.urls'), name='register'),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT) + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
products/urls.py
from django.urls import path
from .import views
urlpatterns = [
path('', views.ProductListView.as_view(), name='products'),
path(r'^products/(?P<id>\d+)/$', views.ProductDetailView.as_view(), name='details')
]
You've got that warning because Django unable to match the url to any of your urlpattern
. Shortly you can use this to solve your problem:
# products/urls.py
from django.urls import path
from .import views
urlpatterns = [
path('', views.ProductListView.as_view(), name='products'),
path('products/<int:pk>/$', views.ProductDetailView.as_view(), name='details')
]
or if you want to use regex to match your url then:
# products/urls.py
from django.urls import path, re_path
from .import views
urlpatterns = [
path('', views.ProductListView.as_view(), name='products'),
re_path(r'^products/(?P<pk>\d+)/$', views.ProductDetailView.as_view(), name='details')
]
The reason is because your ProductDetailView
are inheriting from DetailView
of Django. That View already implemented some mixin to get the object from pk
key instead of id
that's why when you change to use <int:pk>
it'll works.
You can take a look at the source code to see how Django implementing to query the object. (Keep you eyes on SingleObjectMixin
mixin and property pk_url_kwarg = 'pk'
.
I also recommend you to change the value of pk_url_kwarg
in ProductDetailView
view and also remember to change pk
in the urlpattern into the new value which match with pk_url_kwarg
value.