1

I am really struggling trying to get my POST data to bind to this form. POST data is coming through properly and appears to be in the right form, but it absolutely refuses to bind to the form for validation. I'm new to this so I'm sure I'm missing something obvious, but any help figuring out why this is happening would be greatly appreciated.

views.py
def new_call(request):

    if not request.user.is_authenticated():
        return redirect(login_view)

    if request.method == "POST":    

        form = RegisterCallForm(request.POST,user=request.user)

        #Prints False
        print form.is_bound

        if form.is_valid():
            answered = form.cleaned_data['answered']
            left_message = form.cleaned_data['left_message']
            contact_pk = form.cleaned_data['contact']
            time_called = form.cleaned_data['time_called']
            note = form.cleaned_data['note']

            staff_person = request.user.userprofile

            call = Call(
                staff_person=staff_person,
                contact=contact,
                answered=answered,
                left_message=left_message,
                time=time_called,
                note=note,
                )

            call.save()

            if request.POST.get('submit') == 'continue':
                return redirect(user_profile_view)
            else:
                return redirect(new_call)

    else:

        form = RegisterCallForm(user=request.user,)

    return render(request, 'supporttracker/register_call.html',{'form':form})

And here's the form...

forms.py
class RegisterCallForm(forms.Form):

    def __init__(self,*args,**kwargs):

        self.user = kwargs.pop('user',User)
        super (RegisterCallForm, self).__init__(*args,**kwargs)

        self.fields['contact'] = forms.TypedChoiceField(
        choices = get_contact_list(self.user),
        label = 'Call with',
        )

        new_fields = OrderedDict()

        new_fields['contact'] = self.fields['contact']
        new_fields['answered'] = self.fields['answered']
        new_fields['left_message'] = self.fields['left_message']
        new_fields['time_called'] = self.fields['time_called']
        new_fields['note'] = self.fields['note']

        self.fields = new_fields

    answered = forms.TypedChoiceField(
    label='Answered:',
    coerce=lambda x: x == 'Yes',
    choices=((False, 'No'), (True, 'Yes')),
    widget=forms.RadioSelect
    )   

    left_message = forms.TypedChoiceField(
    label='Left a message:',
    coerce=lambda x: x == 'Yes',
    choices=((False, 'No'), (True, 'Yes')),
    widget=forms.RadioSelect
    )

    time_called = forms.DateTimeField(
    label = 'Time of call',
    initial = datetime.datetime.now,
    required = False,
    )

    note = forms.CharField(
    max_length=500,
    widget=forms.Textarea,
    required=False,
    )
  • 1
    It's not that hard to check what's failed the validation. Just add an `else` branch for `if form.is_valid()` then print `form.errors` there, you should see which field gives you error. – Shang Wang Apr 22 '16 at 18:09
  • When I do that, I don't get any errors. I have `print form.is_bound` in there already and it always prints `False` – Nikolai0045 Apr 22 '16 at 18:16
  • The way you construct your form is a little weird I don't know why you do that, so I don't suggest recreating `self.fields`(although it looks right). Have you printed your `request.POST`? Is there anything? – Shang Wang Apr 22 '16 at 18:23
  • I wasn't sure how to reorder the way the fields show up so that's why I recreated `self.fields`. If there's a better way to do that, I'm definitely open to it. Yea `request.POST` has all of the fields with data in them. `` – Nikolai0045 Apr 22 '16 at 18:27
  • http://stackoverflow.com/questions/350799/how-does-django-know-the-order-to-render-form-fields – Shang Wang Apr 22 '16 at 18:30
  • Most of the stuff on that question doesn't work on 1.9, but one of the two answers that applied to 1.9 is what I did. Do you think that's what is causing the issue? That doesn't seem to make sense. – Nikolai0045 Apr 22 '16 at 18:36
  • No, I don't think it would affect anything, but I found changing default django built in data structure very error-prone. I don't see anything that could cause this. – Shang Wang Apr 22 '16 at 18:39
  • 1
    So I found out that, in 1.9, there is now a `forms.order_fields()` method that allows you to reorder the fields for the instance of the form. [link](https://docs.djangoproject.com/en/1.9/ref/forms/api/#django.forms.Form.field_order) – Nikolai0045 Apr 22 '16 at 19:01
  • 1
    Also that fixed my form binding issue somehow – Nikolai0045 Apr 22 '16 at 19:02
  • OK, glad that you found the link. Yea as I said, I'm always having an impression that django is doing extra stuff behind the scene so it's best not to mess around with built in fields. If you are interested, you could read up the source to see what django does for `self.fields` when you call `super`. If it does, whatever you do after will screw it. – Shang Wang Apr 22 '16 at 19:03
  • Makes sense. Thanks! – Nikolai0045 Apr 22 '16 at 19:08

1 Answers1

1

It seems you forget to call super init. How do you expect form class do it's normal job when you override the init function?

Ali Nikneshan
  • 3,500
  • 27
  • 39