0

I thought it looks trivial, and was surprised.

What I have

I have a Django model + form (ModelForm).

My user fills in the form, and on my view I have the usual:

    if request.POST:
        form = myForm(request.POST)
    if request.method == "POST" and form.is_valid():
        result = form.save(commit=False) 

Now I need to heavily manipulate some fields of the form (in the "result" object) and I want to check the forms is_valid() again before saving.

The Problem

I tried to create a new form using the "result" object (that is a ModelForm object) using a dictionary (as suggested here)

result_dictionary = dict((x.name, getattr(result, x.name)) for x in result._meta.fields) 

or

result_dictionary = model_to_dict(result, fields=[field.name for field in result._meta.fields])

plus

testForm = myForm(initial=result_dictionary)

but it doesn't pass is_valid() and does'nt give any errors! The fields are passed OK to the new form...

Any ideas?

Community
  • 1
  • 1
reakh
  • 111
  • 10
  • 1
    is there any reason you are not using the "instance" parameter to create the form from the "result" object? - e.g. testForm = myForm(instance=result) – Derek Kwok Sep 20 '11 at 16:18
  • Happy too early.. This doesn't work right. `testForm.is_bound => False` and also `testForm.is_valid() => False` – reakh Sep 21 '11 at 09:45

1 Answers1

1

Sometimes, looking in the Django source can be really helpful, here's BaseForm.is_valid():

def is_valid(self):
    """
    Returns True if the form has no errors. Otherwise, False. If errors are
    being ignored, returns False.
    """
    return self.is_bound and not bool(self.errors)

So if there are no errors, is_valid() returns false because you haven't bound the form, you haven't given the form anywhere to look for data. Try using the form.data dictionary instead, something like this:

if request.POST:
    form = myModel(request.POST)
if request.method == "POST" and form.is_valid():
    form.data['field1'] = 'Changing this'
    form.data['field2'] = 34

    testform = myModel(data=form.data)
haeric
  • 159
  • 4
  • Without changing the rest I tested `if testForm.is_bound:...` and it returns True. Or is this test wrong? (p.s. I had a typo and corrected my question myModel-->myForm. Doesn't change anything - just to be less confusing) – reakh Sep 20 '11 at 12:33
  • If `testForm.is_bound` is True, and `testForm.errors` is empty as well, then `testForm.is_valid()` should really, really return True, by all logical senses I have ;) Have you tried looking at `testForm.errors`? – haeric Sep 21 '11 at 20:03