Reputation: 3120
I need to call an API function after validating a form with is_valid(). This API call can still throw exceptions which in turn may kind of invalidate a field in the form.
How can I do that? I'm looking for something like that:
def smstrade(request):
if request.method == "POST":
form = SomeForm(request.POST)
if form.is_valid():
try:
api_call(...)
except SomeException:
form["field"].set_valid(False)
Upvotes: 7
Views: 4047
Reputation: 1993
In case you really want to trigger the form validation by calling is_valid
a second this is the way you can do it (Django 1.4)
form = MyForm(data)
form.is_valid()
# ...
form._errors = None
form.is_valid() # trigger second validation
Upvotes: 0
Reputation: 101
Bit late, but you can invalidate the form and add display the appropriate messages by setting form._errors
>>> f.is_valid()
True
>>> f._errors['my_field'] = ['This field caused a problem']
>>> f.is_valid()
False
>>> str(f)
... <ul class="errorlist"><li>This field caused a problem</li></ul>
I needed to do this with FormView.form_valid()
methods and models with unique fields
def form_valid(self, form):
obj = User(**form.cleaned_data)
try:
obj.save()
except IntegrityError:
form._errors['username'] = ['Sorry, already taken']
return super(MyView, self).form_invalid(form)
return super(MyView, self).form_valid(form)
Upvotes: 10
Reputation: 174622
It is better to override the clean method for the field you are interested in and add your logic there. That way, you can output the appropriate error message as well.
Upvotes: 3
Reputation: 118488
Sounds like you just need a variable to store a valid state outside of the form object.
def smstrade(request):
if request.method == "POST":
form = SomeForm(request.POST)
valid = form.is_valid()
if valid:
try:
api_call(...)
except SomeException:
valid = False
if valid: # still valid?
print "VALID!"
But really it seems like you should be putting this in the form itself, so that you only need to call is_valid()
once. The only complication would be if you needed access to the request object.
class MyForm(forms.Form):
def clean(self):
cd = super(MyForm, self).clean()
try:
api_call
except Exception:
raise forms.ValidationError("API Call failed")
return cd
# view..
if form.is_valid():
print "api call success and the rest of the form is valid too."
Upvotes: 1