Question

Below is my code within my views.py. I have a FormView that's being created and prepopulated just fine but when I submit it doesn't go to form_valid(), and when it goes to form_invalid() it doesn't print out any errors.

Any help is much appreciated.

views.py

class CleanTeamMainContactView(LoginRequiredMixin, FormView):
    template_name = "cleanteams/main_contact.html"
    form_class = EditCleanTeamMainContact
    success_url = "mycleancity/index.html"

    def get_initial(self, clean_team_member):
        initial = {}

        if clean_team_member:
            clean_team = clean_team_member.clean_team
            contact_user = clean_team.contact_user

            initial['contact_first_name'] = contact_user.first_name
            initial['contact_last_name'] = contact_user.last_name
            initial['contact_email'] = contact_user.email
            initial['contact_phone'] = clean_team.contact_phone
            initial['clean_ambassadors'] = clean_team.contact_user.id
            initial['clean_team_id'] = clean_team.id

        return initial

    # Initialize the form with initial values
    def get_form(self, form_class): 
        clean_team_member = self.request.user.profile.clean_team_member

        return form_class(
            clean_team=clean_team_member.clean_team,
            initial=self.get_initial(clean_team_member)
        )

    def form_invalid(self, form, **kwargs):
        context = self.get_context_data(**kwargs)
        context['form'] = form

        print form.errors
        return self.render_to_response(context)

    def form_valid(self, form):
        clean_team_id = form.cleaned_data['clean_team_id']

        try:
            clean_team_member =     CleanTeamMember.objects.get(user=self.request.user)
            clean_team_member.clean_team.update_main_contact(form.cleaned_data)
        except Exception, e:
            print e

        return HttpResponseRedirect(u'/clean-team/%s' %(clean_team_id))

forms.py

class EditCleanTeamMainContact(forms.Form):
    # clean_ambassadors = forms.ChoiceField(required=True, label="Clean ambassadors")
    contact_first_name = forms.CharField(required=False, max_length = 128, min_length = 2, widget=forms.TextInput(attrs={'readonly':'readonly'}), label="First name")
    contact_last_name = forms.CharField(required=False, max_length = 128, min_length = 2, widget=forms.TextInput(attrs={'readonly':'readonly'}), label="Last name")
    contact_phone = forms.CharField(required=False, max_length = 128, min_length = 2, widget=forms.TextInput(attrs={'class':'phone-number'}), label="Phone number")
    contact_email = forms.CharField(required=False, max_length = 128, min_length = 2, widget=forms.TextInput(attrs={'readonly':'readonly'}), label="Email address")
    clean_team_id = forms.CharField(required=False, widget=forms.HiddenInput())

    def __init__(self, clean_team=None, *args, **kwargs):
        super(EditCleanTeamMainContact, self).__init__(*args, **kwargs)

        print clean_team
        # Prepopulate the Clean Ambassador drop down
        ctm_queryset = CleanTeamMember.objects.filter(clean_team=clean_team)
        self.fields["clean_ambassadors"] = forms.ChoiceField(label="Clean Ambassadors", widget=None, choices=[(o.user.id, str(o.user.profile.get_full_name())) for o in ctm_queryset])

        print self.fields["clean_ambassadors"].choices

    def clean(self):
        cleaned_data = super(EditCleanTeamMainContact, self).clean()

        contact_phone = cleaned_data.get("contact_phone")

        if not contact_phone:
            raise forms.ValidationError("Please enter a contact phone number")

        return cleaned_data

main_contact.html

{% extends '_public_base.html' %}

{% block title %} My Clean City - Main Contact {% endblock %}

{% block css %}
  <link href="{{ STATIC_URL }}css/mycleancity.css" rel="stylesheet">
{% endblock %}

{% block content %}

<div class="wrapper public">
  <div class="clouds"></div>

  {% include "_loggedin_navbar.html" %}

  <a href="/" class="logo"></a>

  <div class="content">
    <div class="container">
      <a href="#" onclick="history.go(-1); return false;"><div class="sign register" id="sign-go-back"></div></a>
      <div id="white-box" class="small main-contact">
          <h2>Main Contact for {{ user.profile.clean_team_member.clean_team.name }}</h2>
          <span class="subtitle">Select one of the Clean Ambassadors to set them as the primary contact. If their information is incorrect, have them update their information by logging in and going to Edit Profile.</span>

          {% if form.non_field_errors %}
            <div class="message-box error">
            {{ form.non_field_errors }}
            </div>
          {% endif %}

          <form action="" method="post" enctype="multipart/form-data">{% csrf_token %}
            {{ form.clean_team_id }}

            <table>
                <tr>
                  <td colspan="2">{{ form.clean_ambassadors.label_tag }} {{ form.clean_ambassadors }}</td>
                </tr>
                <tr>
                    <td>{{ form.contact_first_name.label_tag }} {{ form.contact_first_name }}</td>
                    <td>{{ form.contact_last_name.label_tag }} {{ form.contact_last_name }}</td>
                </tr>
                <tr>
                    <td>{{ form.contact_email.label_tag }} {{ form.contact_email }}</td>
                    <td>{{ form.contact_phone.label_tag }} {{ form.contact_phone }}</td>
                </tr>
            </table>

            <input class="btn btn-primary" type="submit" value="Update Main Contact" />
          </form>
      </div><!-- /#white-box -->
    </div><!-- /.container -->
  </div><!-- /.about -->
</div> <!-- /.wrapper -->
{% include "_footer_navbar.html" %}

{% endblock %}

{% block javascript %}{% endblock %}
Was it helpful?

Solution

I think the reason why the data isn't being given to the form is because you have overridden the get_form method without passing it the request.POST data. Instead of overriding that method, I think it's more appropriate to override the get_form_kwargs method instead.

class CleanTeamMainContactView(LoginRequiredMixin, FormView):
    template_name = "cleanteams/main_contact.html"
    form_class = EditCleanTeamMainContact
    success_url = "mycleancity/index.html"

    def get_initial(self, clean_team_member):
        ...

    def get_form_kwargs(self):
        clean_team_member = self.request.user.profile.clean_team_member
        kwargs = {
            "initial": self.get_initial(clean_team_member),
            "clean_team": clean_team_member.clean_team
        }
        if self.request.method in ("POST", "PUT"):
            kwargs.update({
                "data": self.request.POST,
                "files": self.request.FILES
            })
        return kwargs

    def form_invalid(self, form, **kwargs):
        ...

    def form_valid(self, form):
        ...

This should hopefully fix the empty form.data issue but I'm not sure if the form will still be invalid or not.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top