Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django form with no errors return False for is_valid()

Tags:

forms

django

I'm generating a form from metadata

class MeasureForm(forms.Form):
    def __init__(self,*args,**kwargs):
        super(MeasureForm,self).__init__()
        measure_id = kwargs['measure_id']
        m = Measure.objects.get(pk=measure_id);
        if (m):
            # add the measure identifier as a hidden field
            self.fields["measure_id"] = forms.IntegerField(initial = m.id , widget=forms.HiddenInput())
            for mp in MeasureParameters.objects.filter(measure = m):
                # get the NVL'ed copy of the parameter
                p = mp.get_parameter_for_measure()
                if not p.is_modifiable:
                    # the file has a constant value
                    if (p.values and p.default): # constant must have both values and default index
                        value_ = p.values[p.values.keys()[p.default-1]];
                        self.fields[p.name] = forms.IntegerField(
                            label = p.description , 
                            initial = value_, 
                            help_text = p.help_text)
                        self.fields[p.name].widget.attrs['readonly'] = True
                    else:
                        raise Exception("Parameter set as unmodifiable but has no value. \
                                        [measure: %s, parameter: %s, measureparameter %s]"
                                        % (m.id , p.id , mp.__unicode__()))
                elif (p.values):
                    # convert hstore dict to list of tuples for the choices to read
                    values_ = [(v, k) for k, v in p.values.iteritems()];
                    # set default if exists , else take the first item
                    default_ = values_[p.default-1][0] if p.default else values_[0][0]
                    self.fields[p.name] = forms.ChoiceField(
                        label = p.description , 
                        choices = values_ , 
                        initial = default_, 
                        help_text = p.help_text)
                else:
                    self.fields[p.name] = forms.IntegerField(label = p.description, help_text = p.help_text)
                if (not p.is_visible):
                    self.fields[p.name].widget = forms.HiddenInput()
        else:
            raise Exception ("Could not find measure. [measure %s]" % (m.id))

    def clean(self):
        return self.cleaned_data;

this is my view

def index(request,measure_id = None):

    owners = Owner.objects.all()    
    form = None
    result = None
    title = None;
    msg = None;

    # handle the form
    if request.method == 'POST': # the form has been submitted
        form = MeasureForm(request.POST, measure_id = request.POST.get('measure_id')) # A form bound to the POST data
        result = -100
        if form.is_valid(): # All validation rules pass
            result = 100
        msg = "%s" % repr(form.errors) # list of validation errors
    else:
        if (measure_id):
            title = Measure.objects.get(pk=measure_id).name;
            # make an unbound form
            form = MeasureForm(measure_id = measure_id)

    return render(request, 'calc/index.html' ,
            {'owners' : owners, 
             'form'   : form , 
             'title'  : title , 
             'result' : result, 
             'debug'  : msg })

this is a snippet from my template

<div class="content">
    {{ form.errors }}
    {{ form.non_field_errors }}
    {% if form %}
        <h2>{{ title }}</h2>
        <form action="/calc/{{m.id}}" method="post">{% csrf_token %}
            {{ form.as_p }}
        <input type="submit" value="Calculate" />
        </form>
    {% if result %}
        The Result is  <span class="result"> {{ result }} </span>
    {% endif %}
</div>

So i get empty braces {} for "%s" % repr(form.errors), form.errors and form.non_field_errors returns nothing. the form posts and I can see the raw data in the request but i keep getting false from is_valid(). why is that ?

EDIT: when checking if the form is bound i also get false. guessing this is the problem. why isn't the form bound after the call for form = MeasureForm(request.POST, measure_id = request.POST.get('measure_id')) ?

** django newbie, Thanks.

like image 775
haki Avatar asked Sep 10 '26 19:09

haki


1 Answers

Because you're not passing the arguments into the super call. You should do this:

    super(MeasureForm,self).__init__(*args, **kwargs)

otherwise the form will never actually be initialised with the POST data.

Edit after comment The answer to that question didn't recommend removing all the arguments from the super call. If you're passing in measure_id you'll simply need to remove it from kwargs beforehand:

def __init__(self, *args, **kwargs):
    measure_id = kwargs.pop('measure_id', None)
    super(MeasureForm,self).__init__(*args, **kwargs)
like image 196
Daniel Roseman Avatar answered Sep 13 '26 13:09

Daniel Roseman