Wednesday, May 27, 2015

Re: Changing a form field's value during cleaning

If you are able to catch the validation error, then perhaps you can redirect users back to the original form URL (since the form should have the new correct values on the next load).

Check out the form.invalid() when working with the form directly or form_invalid() for CBV's. If you catch that specific error in form_invalid(), you can redirect the users back to the original form URL (hopefully with a message explaining what happened), which should display the form with the correct new value(s). However, this will also lose any other changes the user may have submitted.

Alternatively, you can render the invalid form with updated values using the techniques you described, but you may need to do some dictionary digging to figure out where to change the value of the form. I'm on my phone so I can't check really, but I think changing the 'value' attribute on the failed form may work.

Redirecting back to a clean version of the form with an error message is probably easiest, and can serve as a stop gap until you figure out the more desirable behavior.

-James

On May 27, 2015 12:47 AM, "Gergely Polonkai" <gergely@polonkai.eu> wrote:
Hello,

although the data is from the database, the form itself is not a ModelForm derivative. Also, this code you suggest will only modify the model handling part of the form, thus, the user will see a value he entered, although the database holds a different one.

Best,
Gergely

2015-05-27 9:16 GMT+02:00 Klaas Feenstra <klaas@feenstra.es>:
Hi,

Maybe you can solve this in the views.py with commit=False


And from here you can render the new form with the initial data
# Create a form instance with POST data.  >>> f = AuthorForm(request.POST)    # Create, but don't save the new author instance.  >>> new_author = f.save(commit=False)    # Modify the author in some way.  >>> new_author.some_field = 'some_value'    # Save the new instance.  >>> new_author.save()  

On Wed, May 27, 2015 at 2:55 AM, Gergely Polonkai <gergely@polonkai.eu> wrote:

Hello,

I'm currently having hard times changing a form field's value from within the form's clean() method. I have already tried setting self.initial[field_id] and manipulating the cleaned data by calling super's clean method, change the required field (cleaned_data[field_id]) and returning the modified dict, but all for no effect. Trying to change self.data threw me an error saying data is immutable. Question is, is it even possible, even if I had to tamper with "protected/private" properties/methods?

Should I be on the wrong track, I try to outline the problem:

I have a form with fields added programmatically in __init__(). The value of these fields come from one of my models. It is highly possible that another user puts one of the fields in approved state. If this happens, I don't want the current user to be able to change its value, hence I raise a validation error in the field's validate() method.

Now comes the tricky part. In this particular case I want three things to happen:

• warn the user about the fact that the field has already been approved (i.e. display the validation error message)
• render the input field as read only so the user can't modify it (well, at least not in a trivial way)
• and revert the field's value to the one in the database

However, in case of a validation error the field's value remains the "illegal" one the user just entered, and, as the input field is rendered read only, there's no way for him to change it. Thus, I am trying to set it during MyForm.clean() by walking through field errors looking form the proper error code ('already_approved'), and once found, set it back to its database value. This way I hope that my ValidationError remains (hence the warning on the page) while resetting the unchangeable value so at the time of the next submit it won't cause a problem.

Kind regards,
Gergely

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CACczBUK2EEaHBaS7bS%3DJF8Ce35MBkrwugtRvZCJC9E_Ovk2Rqg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAJcivacMBoNMG4OMwwkg7CDyYzOccXjz-3it5OdD_Au0r0trzg%40mail.gmail.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CACczBULF%2BDGgK1Rm%2BLJEsujO0ENZ9SDWvpBqZwog9zczG4C3_g%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CA%2Be%2BciW4JJ0cA_GjPaVb_3jWbb8GOjzpJeRGzNgYKwh_GP%3DdxQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment