Search code examples
djangodjango-viewsdjango-formsinline-formset

inline forms validation errors not in template


I have this model:

class dateEvent(models.Model):

link = models.URLField(null=True, blank=True)
link_description = models.CharField(max_length=30, null=True, blank=True)
event = models.ForeignKey('Event', on_delete=models.CASCADE)

class Event(models.Model):
    title = models.CharField(max_length=200)

[...]

views.py:

def event_edit_view(request, id):
    event = get_object_or_404(Event, id=id)
    form_event = EventForm(request.POST or None), instance=event)
    DateEventFormSet = inlineformset_factory(Event, dateEvent, extra=5, can_delete=True, fields=('event', 'start_date_time', 'venue', 'link', 'link_description'),
    widgets={
    'venue': s2forms.Select2Widget(),
    'link': forms.TextInput(attrs={'placeholder': 'http://'}),
    'start_date_time': CalendarWidget(),
    'description_link': forms.TextInput(attrs={'placeholder': 'Link description'}),
    })
    form_date_event = DateEventFormSet(request.POST or None, instance=Event.objects.get(id=id), prefix="dateEvent", queryset=dateEvent.objects.filter(event__id=id))

    if request.method == "POST":

        if form_event.is_valid() and request.POST['action'] == 'submit':
            if form_date_event.is_valid():
                form_event.save()
                form_date_event.save()
                messages.success(request, 'Event updated successfully. See the <a href="/event-detail/' + str(id) + '">detail page</a>')
                return redirect('my-events')
            else:
                raise forms.ValidationError(form_date_event.errors)

        elif form_event.is_valid() and form_date_event.is_valid() and request.POST['action'] == 'update':
            form_event.save()
            form_date_event.save()

        else:
            raise forms.ValidationError([form_event.errors, form_date_event.errors])

    context = {
        'event': event,
        'id': event.id,
        'form_event': form_event,
        'form_date_event': form_date_event,

        }

    return render(request, "events/event-edit.html", context)

And template:

 <tbody id='date_body'>
  {{ form_date_event.management_form }}
  {{form_date_event}}
 </tbody>

When on the template I input illegal data (say, a non-URL in the URL field) Django throws an error via the ugly debug interface:

ValidationError at myurl...

['Enter a valid URL.']

Request Method:     POST

Or a server error 500 if debug is turned off. Why am I not displaying the error on the template?


Solution

  • The ValidationError should be raised in the form instead of the view. By raising a ValidationError in the view, you aren't rendering the template. This explains why you can see the error in the debug data, but no page is rendered. The 500 error is most likely because your view isn't returning a HTTP response when it raises the error. The documentation has examples of how to raise view and form errors.

    Django HTTP View Errors

    Django Form Validation Errors