Cause of this error: No List matches the given query

Question:

The user can add that product to the watch list by clicking on the add button, and then the add button will change to Rimo. And this time by clicking this button, the product will be removed from the list.
There should be a link on the main page that by clicking on it, all the products in the watch list will be displayed, and by clicking on the detail button, you can see the details of the product, and by clicking on the remove button, you can remove them from the list.

models.py

class User(AbstractUser):
    pass


class List(models.Model):
    choice = (
        ('d', 'Dark'),
        ('s', 'Sweet'),
    )
    user = models.CharField(max_length=64)
    title = models.CharField(max_length=64)
    description = models.TextField()  
    category = models.CharField(max_length=64)      
    first_bid = models.IntegerField()  
    image = models.ImageField(upload_to="img/", null=True)      
    image_url = models.CharField(max_length=228, default = None, blank = True, null = 
             True)
    status = models.CharField(max_length=1, choices= choice)
    active_bool = models.BooleanField(default = True)

class Watchlist(models.Model):
    user = models.CharField(max_length=64)
    watch_list = models.ForeignKey(List, on_deleted= 
                models.CASCADE)

views.py:

def product_detail(request, product_id):
    product = get_object_or_404(List, pk=product_id)
    comments = Comment.objects.filter(product=product)

    if request.method == 'POST':
    
        # comment
        if 'comment' in request.POST:
            user = request.user
            if user.is_authenticated:
                content = request.POST.get('content')
                comment = Comment(product=product, user=user, content=content)
                comment.save()
    

    context = {
        'product': product,
        'comments': comments, 
       }

    return render(request, 'auctions/product_detail.html', context)



 @login_required(login_url="login")
 def watchlist(request, username):
     products = Watchlist.objects.filter(user = username)
     return render(request, 'auctions/watchlist.html', 
           {'products': products})


 @login_required(login_url="login")
 def add(request, productid):
     #watch = Watchlist.objects.filter(user = 
              #request.user.username)
      watchlist_product = get_object_or_404(Watchlist, 
                          pk=productid)

     for items in watchlist_product:
        if int(items.watch_list.id) == int(productid):
            return watchlist(request, request.user.username)
    
    product = get_object_or_404(List, 
               pk=watchlist_product.watch_list)
   new_watch = Watchlist(product, user = request.user.username)
   new_watch.save()
   messages.success(request, "Item added to watchlist")
   return product_detail(request, productid)




@login_required(login_url="login")
def remove(request, pid):
    #remove_id = request.GET[""]
    list_ = Watchlist.objects.get(pk = pid)
    messages.success(request, f"{list_.watch_list.title} is 
         deleted from your watchlist.")
    list_.delete()
    return redirect("index")

product_deyail.html(Only the parts related to the question):

    <form method= "get" action = "{% url 'add' product.id %}">
    
        <button type = "submit" value = "{{ product.id }}"  name 
         = "productid" >Add to Watchlist</button>
    </form>

watchlist.html:

{% extends "auctions/layout.html" %}
{% block body %}

    {% if products %}
        {% for product in products %}
            <img src= {{ product.image.url }} alt = " 
               {{product.title}}"><br>
            <a><a>Product:</a>{{ product.title }}</a><br>
            <a><a>Category: </a>{{ product.category }}</a><br>
            <a><a>Frist Bid: </a> {{ product.first_bid }} $ </a> 
                  <br>
        

            <a href="{% url 'product_detail' product.id %}">View 
                Product</a>

            <form action="{% url 'remove' product.id %}" method="post">
                {% csrf_token %}
                <button type="submit">Remove</button>
            </form>
        {% endfor %}
    {% else %}
        <p>No products in watchlist</p>
    {% endif %}

{% endblock %}

layout.html(Only the parts related to the question & To display the linked name):

<ul class="nav">
        <li class="nav-item">
            <a class="nav-link" href="{% url 'index' %}">Active Listings</a>
        </li>

        <li class="nav-item">
            <a class="nav-link" href="{% url 'watchlist' 
                  user.username %}">My WatchList</a>
        </li>


        {% if user.is_authenticated %}
            <li class="nav-item">
                <a class="nav-link" href="{% url 'logout' %}">Log Out</a>
            </li>
        {% else %}
            <li class="nav-item">
                <a class="nav-link" href="{% url 'login' %}">Log In</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="{% url 'register' %}">Register</a>
            </li>
        {% endif %}

urls.py:

path('watchlist/<str:username>', views.watchlist, 
      name='watchlist'),
path('add/<int:productid>', views.add, name='add'),
path('remove/<int:pid>', views.remove, name='remove'),

error:
Reverse for ‘product_detail’ with arguments ‘(”,)’ not found. 1 pattern(s) tried: [‘product_detail/(?P<product_id>[0-9]+)/Z’]

watchlist.html:

<a href="{% url 'product_detail' product_id %}">View Product</a>
Asked By: zahra shokrizadeh

||

Answers:

<form method="post" action="{% url 'add' %}">  <button type="submit" value="{{ product.id }}" name="productid">Add to  Watchlist</button> </form>

or

product_id = request.GET.get(‘productid’, False)

The reason for your initial error is that <form method= "get" action = "{% url 'add' %}"> is creating a url with the parameter productid, which your path, path('add/', views.add, name='add'), does not handle.

You could change it to

path('add/<int:productid>', views.add, name='add')

and change the view to

def add(request, productid):

Then you wouldn’t need the product_id = request.POST.get('productid', False).

The reason you get

"Reverse for 'product_detail' with arguments '('',)' not found. 1 pattern(s) tried: ['product_detail/(?P<product_id>[0-9]+)/\Z']"

is most likely because the line

<button type = "submit" value = {{ product.id }} name = "productid" >Add to Watchlist</button>

has the value unquoted, so it may not read it, thus sending an empty string back.

Change it to

<button type = "submit" value = "{{ product.id }}" name = "productid" >Add to Watchlist</button>

Answered By: raphael
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.