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>
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>