Page not found (404) No x matches the given query

Question:

I’m not sure of why I can’t get the pk which I think it’s the problem here.
I am trying to do a like functionality to a product model, with a like the page would refresh and the result be shown but it does not save the like and the error Page not found (404) No Product matches the given query.

My Model:

class Product(models.Model):
    author = models.ForeignKey(User, default=None, on_delete=models.CASCADE)
    title = models.CharField(max_length=120, unique=True)
    likes = models.ManyToManyField(User, related_name='like')

    ...

    def number_of_likes(self):
        return self.likes.count()

My views:

class ProductDetailView(DetailView):
    model = Product
    template_name = 'services/product_detail.html'

    def get_context_data(self, **kwargs):
        data = super().get_context_data(**kwargs)

        likes_connected = get_object_or_404(Product, id=self.kwargs['pk'])
        liked = False
        if likes_connected.likes.filter(id=self.request.user.id).exists():
            liked = True
        data['number_of_likes'] = likes_connected.number_of_likes()
        data['post_is_liked'] = liked
        return data

def ProductLike(request, pk):
    post = get_object_or_404(Product, id=request.POST.get('product_id'))
    if post.likes.filter(id=request.user.id).exists():
        post.likes.remove(request.user)
    else:
        post.likes.add(request.user)

    return HttpResponseRedirect(reverse('product-detail', args=[str(pk)]))

My urls:

path('product/<int:pk>/', ProductDetailView.as_view(), name='product-detail'),
path('product-like/<int:pk>/', ProductLike, name="product_like"),

My template:

        {% if user.is_authenticated %}
        <form action="{% url 'product_like' object.id %}" method="POST">
            {% csrf_token %}
      
            {% if post_is_liked %}
                <button type="submit" name="blogpost_id" value="{{object.id}}" >Unlike</button>
            {% else %}
                <button type="submit" name="blogpost_id" value="{{object.id}}">Like</button>
            {% endif %}
        </form>
        {% else %}
            <a href="{% url 'login' %}?next={{request.path}}">Log in to like this article!</a><br>
      {% endif %}
      <strong>{{ number_of_likes }} Like{{ number_of_likes|pluralize }}</strong>

Asked By: nameless

||

Answers:

A couple of things that could be giving you problems:

In your redirect for ProductLike you use args

return HttpResponseRedirect(reverse('product-detail', args=[str(pk)]))

But when you get back to the view, you are looking for kwargs

likes_connected = get_object_or_404(Product, id=self.kwargs['pk'])

Try using kwargs in your redirect

return HttpResponseRedirect(reverse('product-detail', kwargs={'pk': pk}))

Also, in your ProductLike view you are referring to request.POST.get('product_id'))

However, you are not sending any fields by the name product_id. It looks like the like form sends blogpost_id, so the lookup in the view will always 404.

Answered By: SamSparx
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.