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...@googlegroups.com.
To post to this group, send email to django...@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.
Because it is possible that user A will load the page, and user B will approve the field.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CALn3ei2dZX1KWd-SQ1S9VJ%3DbK8bN9Xj1MKvb7jS-zNyvxSz3Aw%40mail.gmail.com.
# 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()
--
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAJcivacMBoNMG4OMwwkg7CDyYzOccXjz-3it5OdD_Au0r0trzg%40mail.gmail.com.
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
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CACczBULF%2BDGgK1Rm%2BLJEsujO0ENZ9SDWvpBqZwog9zczG4C3_g%40mail.gmail.com.
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.