Reputation: 1183
I'm trying to list a group of deals by category
I have a Deal model and a Category Model, where the Category is a Foreign Key of a Deal like so:
class Deal(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=140, unique=True)
description = models.TextField(default='')
category = models.ForeignKey(Category)
The urlpattern for a category page looks like this:
url(r'^category/(?P<category>\w+)/$', deals_by_category, name='category')
and other urls look like this:
url(r'^all/$', DealListView.as_view(), name='deals'),
url(r'^(?P<slug>.*)/$', deal_by_detail, name='deal_detail'),
url(r'^category/(?P<category>\w+)/$', deals_by_category, name='category'),
url(r'^home/$', DealHome.as_view(), name='deal_home'),
url(r'^test/$', Home.as_view(), name='deal_test'),
url(r'^(?P<pk>[0-9]+)/like', like, name='like'),
The view for this urlpattern is this:
def deals_by_category(request,category):
category_deals = Deal.objects.filter(category__name=category,
)
return render(request, 'deals/category.html', {'category_deals': category_deals})
my other views look like this:
class DealListView(generic.ListView):
model = Deal
context_object_name = 'deal_list'
queryset = Deal.objects.all()
template_name = 'deal_list.html'
class DealHome(generic.TemplateView):
model = Deal
template_name = 'deals/test.html
def deal_by_detail(request, slug):
deal_detail = Deal.objects.get(slug=slug)
return render(request, 'deals/deal_detail.html', {'deal_detail': deal_detail})
def like(request, pk):
if request.method == 'POST':
deal = Deal.objects.get(pk=pk)
deal.likes_total += 1
deal.save()
return redirect('home')
and then my category.html template is looping through these returned deals like this:
{% for deal in category_deals %}
<h5 class="card-retailer">{{ deal.retailer}}</h5>
<p class="card-title">{{ deal.title }}</p>
Now the issue arises if i click on predetermined category link like this:
http://localhost:8000/deals/category/Apparel/
but the error is pointing NOT to my 'deals_by_category' view, but to the individual view for each deal---the stack trace is pointing to that second line below. I think this must be an easy fix, but have been staring at this for the past few hours and can't determine what the issue is.
def deal_by_detail(request, slug):
deal_detail = Deal.objects.get(slug=slug)
return render(request, 'deals/deal_detail.html', {'deal_detail': deal_detail})
Note here is the full error and traceback:
DoesNotExist at /deals/category/Apparel/
Deal matching query does not exist.
Request Method: GET
Request URL: http://localhost:8000/deals/category/Apparel/
Traceback:
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\core\handlers\base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\crstu\Desktop\JSPROJ\dealmazing\deals\views.py" in deal_by_detail
22. deal_detail = Deal.objects.get(slug=slug)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\manager.py" in manager_method
122. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\crstu\AppData\Local\Programs\Python\Python36-32\lib\site-packages\django\db\models\query.py" in get
387. self.model._meta.object_name
Exception Type: DoesNotExist at /deals/category/Apparel/
Exception Value: Deal matching query does not exist.
Upvotes: 0
Views: 152
Reputation: 8891
As pointed out by the stack trace this is where the problem arises.
deal_detail = Deal.objects.get(slug=slug)
The exception DoesNotExist
arises when use get
and the object does not exist. So that means that the slug you're trying to use does not exist in the database.
As you wanted to get category view and not the detail view the error actually lies in the regex (as you rightfully suspected). The error lies in you using .*
which is greedy and uses all of the rest remaining characters.
If you instead change your regex to the following. r'^s/(?P<slug>\w+)/$'
, note the s
in the beginning that helps with keeping the url different from other urls as well \w+
that only uses alphanumeric characters.
Upvotes: 2
Reputation: 599628
Your deal_by_detail
URL pattern captures any sequence of characters. So it will match any URL; none of the other patterns below it will ever be called.
You should make that much more specific, just as you have for the category
pattern.
url(r'^(?P<slug>\w+)/$', deal_by_detail, name='deal_detail'),
Upvotes: 2