I have an app with a bunch of POST request on a path that looks like this:
path("auctions/<str:title>", views.listing, name="listing")
It's a sort of auction app, where users can create listings, and others can place bids and purchase these items.
When a user clicks on one of these items, ive got this function that takes them to a page where they can get all details about the listing that they have just clicked and they can do things like place a bid or place the item in their watchlist.
views.py
def listing(request, title):
if request.method == "POST":
if watchlist.is_valid():
if "watchlist" in request.POST:
watchlist_data = Watchlists.objects.all().filter(title=title, user=username).first()
if watchlist_data:
watchlist_data.delete()
else:
true_wtchlist = Watchlists.objects.create(title=title, user=username)
ps: watchlist here is just an example of one of the conditions under my function, i just posted it as an example, even though i will appreciate any errors beign pointed out if any is noticed.
I can usually get the title
of the listing that was clicked from the title
argument that gets passed here def listing(request, title):
, and i use this title to query the database.
Now I am trying to add a 'Close listing' button to the page so that the user that posted the listing can close it after the item has been sold to the highest bidder, and this is what I have:
template
{% if user.username == users %}
<form action="listing" method="POST">
{% csrf_token %}
<input type="submit" value="Close Listing" name="close">
</form>
{% endif %}
views.py
if "close" in request.POST:
bid = Bid.objects.all().filter(title=title, price=max_bid).first()
max_bid_user = bid.user
listing_object.tag = 'closed'
listing_object.save()
if username == max_bid_user:
return render(request, "auctions/listing.html", {
"message": "Thank you for your entry into this auction. You have emerged the winner and this listing has been closed"
})
I was getting a bunch of errors, so i tried to debug and i noticed it gets the incorrect title from the path
request:<WSGIRequest: POST '/auctions/listing'>
and i have the path and path info lookin like:
path: '/auctions/listing'
path_info: 'auctions/listing'
and so title also looks like:
title: 'listing'
NB: 'listing' is the name of the path
Can someone explain to me whats happening here and why?
someone said to share entire listing view:
@login_required
def listing(request, title):
commentform = CommentForm()
checkbox = CheckForm()
form = BidForm()
listing_object = Listing.objects.all().filter(title=title).first()
user = listing_object.user
if request.user.is_authenticated:
username = request.user.get_username()
bids = Bid.objects.all().filter(title=title).values_list("price", flat=True)
max_bid = max(bids)
if request.method == "POST":
watchlist = CheckForm(request.POST)
bid = Bid(title=title, user=username)
bidform = BidForm(request.POST, request.FILES, instance=bid)
if watchlist.is_valid():
if "watchlist" in request.POST:
watchlist_data = Watchlists.objects.all().filter(title=title, user=username).first()
if watchlist_data:
watchlist_data.delete()
else:
true_wtchlist = Watchlists.objects.create(title=title, user=username)
if bidform.is_valid():
price = bid.price
if not bids:
bid = bidform.save()
return render(request, "auctions/listing.html", {
"message": "Your bid has been placed succesfully",
"form": form,
"listing": listing_object,
"commentform": commentform,
"checkbox": checkbox
})
else:
max_bid = max(bids)
if price >= listing_object.price and price > max_bid:
bid = bidform.save()
return render(request, "auctions/listing.html", {
"message": "Bid price must be equal or greater than starting price and higher than highest bid",
"form": form,
"listing": listing_object,
"checkbox": checkbox,
"commentform": commentform,
"max_bid": max_bid
})
else:
return render(request, "auctions/listing.html", {
"message": "Bid price must be equal or greater than starting price and higher than highest bid",
"form": form,
"listing": listing_object,
"checkbox": checkbox,
"commentform": commentform,
"max_bid": max_bid
})
if "close" in request.POST:
bid = Bid.objects.all().filter(title=title, price=max_bid).first()
max_bid_user = bid.user
listing_object.tag = 'closed'
listing_object.save()
if username == max_bid_user:
return render(request, "auctions/listing.html", {
"message": "Thank you for your entry into this auction. You have emerged the winner and this listing has been closed"
})
return render(request, "auctions/listing.html", {
"form": form,
"listing": listing_object,
"checkbox": checkbox,
"commentform": commentform,
"max_bid": max_bid,
"users": user
})
Now that I had to share the entire thing I can see how messy it is, any corrections are welcome though.
CodePudding user response:
You should use url tags in action
instead of action='listing'
so:
<form action="{% url 'listing' listing_object.title %}" method="POST">
{% csrf_token %}
<input type="submit" value="Close Listing" name="close">
</form>
Note: Always add
/
at the end of every route so in urls.py it should bepath("auctions/<str:title>/"....)