DaniPilot
DaniPilot

Reputation: 124

Custom Django form doesn't validate

I've been working for some days in a Django validation problem using a form. After days looking out how to resolve it, I find that data isn't being validated. My Django form doesn't return any kind of error (even if i put the error tags in the template).

Instead of using {{ form }}, I decided to do a custom form, creating an HTML code and putting manually all the Django form fields. Before doing this and using simply {{ form }} the form worked correctly

Here I pass you fragments of my code:

template.html:

    <form action="/next_direction/" method="post">
            {% csrf_token %}

    {{ form.errors }}
    {{ form.non_field_errors }}

            Elementa: {{ form.elementa }}<br/>
            Elementb: {{ form.elementb }}<br/>
            Elementc: {{ form.elementc }}<br/>

            {% for hidden in form.hidden_fields %}
                    {{ hidden }}
            {% endfor %}
            <input type="submit" value="Enviar">

    </form>

Now, in forms.py:

from django import forms
from django.utils.translation import ugettext_lazy as _
from alta_tecnologias.models import Tecnologia
import datetime
from django.forms.extras.widgets import SelectDateWidget
from django.core.exceptions import ValidationError

class AltaTecnologias(forms.ModelForm):
    def __init__(self, *args, **kwargs):
            super(AltaTecnologias, self).__init__(*args, **kwargs)
            self.fields['fecha'].initial = datetime.date.today()


    elementa = forms.CharField(widget=forms.TextInput())
    elementb = forms.CharField(widget=forms.TextInput())
    elementc = forms.CharField(widget=forms.TextInput())
    fecha = forms.DateField(widget=forms.HiddenInput())

    def clean(self):
            cleaned_data = super(AltaTecnologias, self)
            return self.cleaned_data

    class Meta:
            model = Tecnologia

And in views.py:

from django import shortcuts
from django.shortcuts import render
from django.contrib.auth.decorators import login_required
from django.template import Context, loader, RequestContext
from alta_tecnologias.forms import AltaTecnologias
from alta_tecnologias.models import Tecnologia
from django.http import HttpResponse, HttpResponseRedirect

@login_required
def alta_tecnologias(request):
        if request.POST:
                form = AltaTecnologias(request.POST)
                if form.is_valid():
                        form.save()
                        return HttpResponse("OK")

        context = Context({'is_auth': str(request.user.is_authenticated()), 'form': AltaTecnologias()})
        template = loader.get_template("alta_tecnologias.html")
        return render(request, 'alta_tecnologias.html', context)

I did many changes on my code following other answers I found on the web, but anyone seems to work on my code.

Thanks for your help!

Upvotes: 1

Views: 1394

Answers (2)

Daniel Roseman
Daniel Roseman

Reputation: 600026

You're always re-instantiating the form before passing it to the template, so the errors from the posted version will be lost. Instead, only instantiate one time for each of GET and POST.

    if request.POST:
            form = AltaTecnologias(request.POST)
            if form.is_valid():
                    form.save()
                    return HttpResponse("OK")
    else:
        form = AltaTecnologias()

    context = {'form': form}
    return render(request, 'alta_tecnologias.html', context)

Not that you don't need to create a Context object, and your call to get_template is completely unnecessary, as both of these things are done by the render function. Also note you can access {{ user.is_authenticated }} directly in the template, so there's no point in passing it in explicitly. Plus, as Lukas states, your override of clean does nothing, so you might as well remove it.

Upvotes: 2

Lukas Kozlowski
Lukas Kozlowski

Reputation: 456

def clean(self):
        cleaned_data = super(AltaTecnologias, self)
        return self.cleaned_data

should be:

def clean(self):
        cleaned_data = super(AltaTecnologias, self).clean()
        return cleaned_data

anyway, I don't see any point in overriding clean method, when you don't do any checks against your data.

Upvotes: 2

Related Questions