Wizard
Wizard

Reputation: 503

Django forms, form is always invalid

Yes, I did look at the other responses to similar questions. But I haven't found one that helps me, Ive looked at all the currently available solutions.

I am trying to enter a name into a textbox, and then hit submit, allowing me to create a new list of items (the items are irrelevant).

But when I hit the submit button nothing happens. After many print statements, Ive deduced that the reason why is because the form.is_valid() function is returning false

if response.method == "POST":
    # returns a dictionary of information in the form
    form = CreateNewList(response.POST)

    print(form.errors)
    # if the form is valid, get the name attribute and create a new ToDoList with it
    if form.is_valid():
        n = form.cleaned_data["name"]
        t = ToDoList(name=n)
        t.save()

        return HttpResponseRedirect("/%i" % t.id)
else:
    form = CreateNewList()

return render(response, "main/create.html", {"form": form})

After reading some posts I found online, the next step I took was printing out the errors using forms.errors This is what I got from that print out

<ul class="errorlist"><li>check<ul class="errorlist"><li>This field is required.</li></ul></li></ul>

At this point, I have no clue what check is or does. One persons response online said that it is part of some dictionary and I have to do something like form['check'] = 1, but when I do that it says the dictionary is immutable or an invalid statement. I also tried form.data['check']=1, same thing

Here is the function that creates a new list

class CreateNewList(forms.Form):
    name = forms.CharField(label="Name", max_length=200)
    check = forms.BooleanField(label="Completed", required=True)

Upvotes: 0

Views: 2585

Answers (2)

Wizard
Wizard

Reputation: 503

I got my desired outcome but I don't know how. Here is the chain of events:

Dawid Mszanowski suggested that I change the value of required to False and set initial to true like this

check = forms.BooleanField(label="Completed", initial=True)

And I tried this earlier and I was still getting errors, didnt work, but I kept the change

Then I implemented what MarkWalker suggested by implementing the check box into my User interface and allowing the user to manually check it off, this actually did fix the problem and I got what I was looking for. Then I reverted all the changed Dawid suggested I make and my program was still running as intended so it seemed as though Marks solution fixed everything. But I didnt like how the user had to manually click the checkbox so I took that off. I was pretty much back to square 1 at this point right? I reverted the changes that Dawid suggested AND the changes that Mark suggested. And now for some reason my program decides to work. Not sure what happened but hey, thanks guys I really appreciate it

Upvotes: 0

mszan
mszan

Reputation: 558

To get started with this issue, you should do the following:

  • Replace response.method with request.method. This is because you want the view to know what was the request's method, not the response's.
  • Replace response.POST with request.POST. This is because you want to populate data from previous POST request.

Back to the topic, your Boolean field is marked as a required field (required=True) and that's why you cannot pass the validation without having related checkbox checked. If you want the checkbox to be checked by default (on first GET request) and not to be required, use initial=True instead of required=True.

Read more in related question.

Upvotes: 1

Related Questions