Avinash Raj
Avinash Raj

Reputation: 174696

Django Form Field Validation failed to work

Here is my form.

class POICreateForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(POICreateForm, self).__init__(*args, **kwargs)
        self.fields['latitude'].widget = HiddenInput()
        self.fields['longitude'].widget = HiddenInput()
        self.fields['picture'].required = True

    class Meta:
        fields = ['name', 'vip', 'category', 'place', 'latitude', 'longitude', 'picture', 'website', 'description',
                  'phone',
                  'email']
        model = PointOfInterest

    def clean(self):
        cleaned_data = super(POICreateForm, self).clean()
        pic = cleaned_data.get('picture', None)
        if not pic:
            msg = 'You must Choose an image'
            self.add_error('picture', msg)

        return cleaned_data

I have given required=True for picture field and also I overridded the clean method. BUt both failed to show the validation error.

Here is my view

class POIFormCreateView(LoginRequiredMixin, CreateView):
    login_url = '/login/'
    model = PointOfInterest
    form_class = POICreateForm
    success_url = reverse_lazy('POIs')

    def post(self, request, *args, **kwargs):

        query_dict = request.POST.dict()
        super(POIFormCreateView, self).post(request, *args, **kwargs)
        filtered_dict = {i: j for i, j in query_dict.items() if i.endswith('day')}

        out = PointOfInterestQuery.create_or_update_open_hours(filtered_dict)
        if out:
            return HttpResponseRedirect(reverse('POIs'))
        return HttpResponse('Error :(')

template.html

{% extends 'base.html' %}
{% load crispy_forms_tags %}

{% block content %}
    <script type="text/javascript">

    </script>
    <h1>New Point Of Interest</h1>

    <form role="form" method="POST" action="/poi/add/" class="post-form form-horizontal"
          enctype="multipart/form-data" name="poi_create" onsubmit="return validateForm()">{% csrf_token %}
        <div class="container row">
            <div class="col-lg-6">
                <!-- customizing form -->
                {{ form|crispy }}
                <!-- End of customization -->
            </div>
            <div class="col-lg-6">
                <div id="map"></div>
                {% include 'open_hours.html' %}
            </div>
        </div>
                    <button type="submit" id="poi-submit" class="save btn btn-default btn-primary center-block">Save
                </button>
    </form>
    <div class="modal-footer"><a href="/poi/">
        <button type="button" class="btn btn-default btn-danger center-block">Cancel
        </button>
    </a></div>

{% endblock %}

Upvotes: 2

Views: 80

Answers (1)

Daniel Roseman
Daniel Roseman

Reputation: 599470

You've overridden the post method and avoided using the form at all. All of this logic should be in the form_valid method instead; that allows the CreateView to do the normal job of form validation and re-displaying the page with errors if the form is invalid, while your processing happens if the form is valid.

Note also however that you should be getting your values to populate filtered_dict from the form's cleaned_data dict, not directly from request.POST.

class POIFormCreateView(LoginRequiredMixin, CreateView):
    login_url = '/login/'
    model = PointOfInterest
    form_class = POICreateForm
    success_url = reverse_lazy('POIs')

    def form_valid(self,form):
        super(POIFormCreateView, self).form_valid(form)
        filtered_dict = {i: j for i, j in self.request.POST.items() if i.endswith('day')}

        out = PointOfInterestQuery.create_or_update_open_hours(filtered_dict)
        if out:
            return HttpResponseRedirect(reverse('POIs'))
        return HttpResponse('Error :(')

Upvotes: 1

Related Questions