Home > front end >  How to handle two Django forms in one view?
How to handle two Django forms in one view?

Time:06-16

I have a view that contains two Django forms. They were previously working but now whichever one is underneath the top one does not work. I have tried switching the order of the forms and whichever form is on the top will work while the other one will not do anything when submitted.

I tried changing my forms so they resemble this example if request.method == "POST" and "selectgenderform" in request.POST: but that did not work (the forms did nothing).

Does anyone know how to fix this problem?

part of views.py

def listing(request, id):
    #gets listing
    listing = get_object_or_404(Listings.objects, pk=id)
    #code for comment and bid forms
    listing_price = listing.bid
    sellar = listing.user
    comment_obj = Comments.objects.filter(listing=listing)
    #types of forms
    comment_form = CommentForm()
    bid_form = BidsForm()

    #code for the bid form
    bid_obj = Bids.objects.filter(listing=listing)
    other_bids = bid_obj.all()
    max_bid =0
    for bid in other_bids:
        if bid.bid > max_bid:
            max_bid = bid.bid
    #checks if request method is post for all the forms
    if request.method == "POST":
        print(request.POST)
        #forms
        comment_form = CommentForm(request.POST)
        bid_form = BidsForm(request.POST)
        #checks if bid form is valid
        if bid_form.is_valid():
            print('!!!!!form is valid')
            #print("bid form is valid")
            print(listing.bid)
            new_bid = float(bid_form.cleaned_data.get("bid"))
            if (new_bid >= listing_price) or (new_bid > max_bid):
                bid = bid_form.save(commit=False)
                bid.listing = listing
                bid.user = request.user
                bid.save()
                print("bid form is saving")
            else: 
                print(bid_form.errors)
                print("bid form is not saving")
                return render(request, "auctions/listing.html",{
                    "auction_listing": listing,
                    "form": comment_form,
                    "comments": comment_obj,
                    "bidForm": bid_form,
                    "bids": bid_obj,
                    "message": "Your bid needs to be equal or greater than the listing price and greater than any other bids."
                })
        else:
            print(bid_form.errors, bid_form.non_field_errors)
            print(bid_form.errors)
            return redirect('listing', id=id)

        #checks if comment form is valid
        if comment_form.is_valid():
            print("comment is valid")
            comment = comment_form.save(commit=False)
            comment.listing = listing
            comment.user = request.user
            comment.save()
        else:
            return redirect('listing', id=id)

Currently, the bid_form is working because it is on the top, but if you flip the order the comment_form will work instead and the bid_form will not.

forms.py

class CommentForm(forms.ModelForm):
    class Meta:
        model = Comments
        fields = ['comment']
        widgets = {'comment': forms.TextInput(attrs={'placeholder': 'Add a comment about this listing here.', 'class' : 'form-control'})}

class BidsForm(forms.ModelForm):
    class Meta:
        model = Bids
        fields = ['bid']
        widgets = {'title': forms.NumberInput(attrs={'placeholder': 'Add a bid for this listing here.', 'class' : 'form-control'})}

CodePudding user response:

You have a flow problem. If the user submits a comment, then your bid_form is invalid, and so it goes to the 'else' section of the if bid_form.is_invalid(), which redirects to another page before the comment form is tested. Thankfully they both have the same else statement, so you can use elif rather than two else...ifs

Assuming only one form can be submitted at a time, try the following:

if bid_form.is_valid():
     ... #remove the else: statement
elif comment_form.is_valid():
     ...
else:
    return redirect('listing', id=id)

If both forms can be submitted at once and should both be handled, you will need to set a flag instead, eg:

if bid_form.is_valid():
    ...
else:
    redirect_later = True
if comment_form.is_valid():
    ...
else:
    redirect_later = True
if redirect_later:
    return redirect('listing', id=id)
  • Related