Getting incorrect title in the URL path Django

Question:

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 class="btn btn-primary" 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.

Asked By: jeddah

||

Answers:

You should use url tags in action instead of action='listing' so:

<form action="{% url 'listing' listing_object.title %}" method="POST">
            {% csrf_token %}
            <input class="btn btn-primary" type="submit" value="Close Listing" name="close">
</form>

Note: Always add / at the end of every route so in urls.py it should be path("auctions/<str:title>/"....)

Answered By: Sunderam Dubey