Search code examples
pythondjangoinputrequesthidden

(Django - Python) Hidden Input Request to views.py


I have to create a site with auctions and I have an homepage which shows all the auctions active...

I want to redirect users to auctions details clicking on relative button but I have some problems with the hidden input request because it doesn't report the hidden value to my function ( def bid (request, auction) ) but I see it on the url bar after the csrfmiddlewaretoken (id=1), can you help me? (I have tried also with POST request...)

These are my codes:

  • views.py
 def home(request):

 auctions = Auction.objects.filter(status=True)

 form = detailForm(request.GET or None)

 if request.method == "GET":

     id = request.GET.get("id")

     if form.is_valid():

         [bid(request,auction) for auction in auctions if auction.id==id]

     else:

         form = detailForm()

 return render(request, "index.html", {"auctions":auctions, "form":form})
def bid(request, auction):

user = request.user

form = bidForm(request.POST)

if request.method == "POST":

    bid = request.POST.get("endPrice")

    if form.is_valid():

        if bid > auction.startPrice:

            auctionUpdate=form.save(commit=False)
            auctionUpdate.endPrice=bid
            auctionUpdate.winner=user
            auctionUpdate.save()

        else:

            messages.warning(request, "Devi puntare una cifra superiore a quella vincente!")
    else:

        form = bidForm()

return render(request, "bid.html", {"form":form})
  • forms.py
class detailForm(forms.ModelForm):

class Meta:
    model = Auction
    fields = ("id",)
  • index.html

    {% for auction in auctions %}
    <--! I put all the informations about auctions -->
    <form method="GET">
    {% csrf_token %}
       <input type="hidden" name="id" value={{auction.id}}>
       <input type="submit">
    {% endfor %}
    </form>
    

Thanks to everyone!


Solution

  • Not sure if I understand your question correctly, so basically we have a list of auctions, and when a user clicks on a related button of an auction, the user will be redirected to another page.

    In this model, you need to think about 2 views and 2 templates to handle them. A ListView to list all your actions and a DetailView to handle the detail page of each auction. So you will have a home.html for your ListView and a bid.html for your auction detail.

    I think the form submission should be implemented in your detail view (in your code the bid function), and the detail view should render a page with the bid.html template.

    In your home.html you may want to just leave a link of each auction like:

    {% for auction in auctions %}
    
    <a type='button' href="{{ auction.get_absolute_url }}">{{ auction.name }}</a>
    
    {% endfor %}
    

    You need to add this get_absolute_url method in your Auction model, for example:

    # models.py
        def get_absolute_url(self):
            return reverse("auction-detail", kwargs={"pk": self.pk})
    

    Also in your routing:

    # urls.py
    urlpatterns = [
        path('/', home, name='home'),
        path('/auctions/<int:pk>/', bid, name='auction-detail'),
    ]
    

    You need to pass auction to your context variable in your bid function as well, in order to refer to it in your template.

    def bid (request, auction_id):
        auction = Auction.objects.get_object_or_404(id=auction_id)
        # ...
        context = {'form': form, 'auction': auction}
        return render(request, "bid.html", context)
    

    And finally in your detail view template (bid.html), use the form to submit:

    <form method="POST">
    {% csrf_token %}
       {{ form.as_p }}
       <input type="hidden" name="id" value={{auction.id}}>
       <input type="submit">
    </form>
    

    Another suggestion is that try to use Class Based View such as ListView and DetailView in this case, which will handler your problem much easier. Check this article for more detail.