Davison
Davison

Reputation: 1

How to override/update information from POST when creating model

I have a view that handles a POST request and attempts to create a new object. However, I know that some of the POST'd data is invalid... But I want to fix it and go ahead and create the object.

The only way I can figure out to be able to 'fix' data in a ModelForm is to create a 'is_valid()' form. To do this, I can either create the form with the POST data, or I can create it with an already existing instance. Unfortunately, if I use the POST data, because some of it is invalid, the form won't validate and I am thus unable to get to the data in the form to fix it. If I create it with an already existing instance, this works, but when the form is displayed, any remaining errors are for whatever reason ignored (and thus don't show up on the web page). I've tried a combination of creating the the Model form from the POST data and giving it an instance, but this doesn't seem to help. Additionally, I've tried modifying (a copy of) the POST data, fixing it, and then creating the ModelForm from the 'fixed' POST data. This sort of works, with the exception that I have some ImageFields in my form, and they seem to just be ignored.

Perhaps there is a better way to do this? The problem I'm trying to solve is that I want to have a model that contains ImageFields. The first time I put up the form, the user needs to 'upload' images for each of the fields. However, if he doesn't update an image for one of the fields, I want the new form to come up with a Image upload button on the fields where images have not been uploaded, and just a text field with the image name for images that have been uploaded.


Ok, I think I can simplify all of the above question into this:

def testing(request):
    test_form = UserProfileForm()
    valid = test_form.is_valid()

    return render('testing.tmpl', locals(), request)

When the above code is rendered, the 'valid' shows as False (as one might expect), but the 'test_form' renders without any errors. I've read through (if perhaps not understood?) the documentation on Models and ModelForms, and I see that most of the time a ModelForm (in my case: UserProfileForm) is created with a specified 'instance'. However, 1) I don't have an instance yet, 2) I would still expect the non-instance'd Form to display errors. I'm sure there is something I am missing. Please illuminate. :)

One more thing, which perhaps the answer to the above will answer anyway, but as far as I can tell, the is_valid() call is supposed to call the 'clean()' function I defined for the UserProfileForm. However, (not being a python guru) I placed 'raise ValidationError()' at the top of clean(), and when I run the code, no error is shown. Thoughts?

Upvotes: 0

Views: 369

Answers (3)

Bernhard Vallant
Bernhard Vallant

Reputation: 50786

You should have a look at how to clean form fields in Django. You could either manipulate the data returned from the form there or make any kind of validation!

Upvotes: 1

Davison
Davison

Reputation: 1

After figuring out how to use the Python debugger (pdb) and the fact that within Emacs it kind of 'just works', I was able to find that my (empty) form was not bound. Googling bound forms pointed me to this page:

The Forms API

RTFM'ing I find that I can pass an empty dictionary to my form and then everything starts to behave as I would expect. So, to summarize, there is a big difference between:

test_form = UserProfileForm()

and

test_form = UserProfileForm( {} )

The second version causes the rendering of the form to show all the errors (and to call 'clean()').

Upvotes: 0

aptwebapps
aptwebapps

Reputation: 1876

If your ImageFields are optional then you can still validate them (that they are otherwise correct).

Then it's a matter of adjusting your template to show either the uploaded file name or an file upload field depending on whether they've already uploaded one or not. Actually, it would probably be better to give them both fields in the first case. That's what the automatic admin does (the upload field is labeled "Change").

Upvotes: 0

Related Questions