Django/python: How to pass the form.cleaned_data value to HttpResponseRedirect as an argument?

943 Views Asked by At

I wanted to pass an argument (form field value) in an URL as below. But when I do this, it raises an error

not enough arguments for format string

I would appreciate help me in solve this or suggest me an alternate approach for passing a form_cleaned value to HttpResponseRedirect.

def phone(request):
    form = PhoneForm(request.POST or None)
    if form.is_valid():

        instance = form.save(commit=False)
        Phone = form.cleaned_data.get('Phone')
        instance.save()
        form.save()
        return HttpResponseRedirect('http://send_sms.com/api_key=api&to=%s&message=Welcome%20to%messaging' %Phone)

    context = {
    "form": form,
    }
    return render(request, "phone.html", context)
3

There are 3 best solutions below

0
On BEST ANSWER

The problem is that Python is treating the other % signs in your string as placeholders as well.

You could double up the other percent signs (e.g. Welcome%%20), or use .format(Phone), but a safer approach would be to get Python to take care of encoding the querystring for you.

from urllib.parse import urlencode # Python 3
# from urllib import urlencode # Python 2

query = {
   'api_key': 'api',
   'to': Phone,
   'message': 'Welcome to messaging',
}
url = 'http://send_sms.com/?%s' % urlencode(query)
return HttpResponseRedirect(url)

This is hopefully more readable and decreases the chances of mistakes. For example, in your question, you have % instead of %20 in %messaging.

2
On

Have you tried this ?

from urllib.parse import urlencode # Python 3
# from urllib import urlencode # Python 2

def phone(request):
    form = PhoneForm(request.POST or None)
    if form.is_valid():
        instance = form.save(commit=False)
        argument = form.cleaned_data.get('Phone')
        instance.save()
        # form.save() -- redundant here imho
        return HttpResponseRedirect(
        'http://send_sms.com/api_key=api&to={}&message=Welcome%20to%messaging'.format(urlencode(argument))
        )

    context = {
       "form": form,
    }
    return render(request, "phone.html", context)

You are using outdated format for string substitution. And also you don't need form.save because your form is an instance so instance.save() would be enough.

0
On

You could try doing this format instead:

return HttpResponseRedirect('http://send_sms.com/api_key=api&to={}&message=Welcome%20to%messaging'.format(Phone))

The string substitution you are using is becoming outdated. This may be a better approach for long-term solutions.