Quería pasar un argumento (valor de campo de formulario) en una URL como se muestra a continuación. Pero cuando hago esto, genera un error

no hay suficientes argumentos para la cadena de formato

Agradecería ayudarme a resolver esto o sugerirme un enfoque alternativo para pasar un valor form_cleaned a 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)
1
sumanth 13 ene. 2017 a las 19:22

3 respuestas

La mejor respuesta

El problema es que Python está tratando los otros signos % en su cadena como marcadores de posición también.

Puede duplicar los otros signos de porcentaje (por ejemplo, Welcome%%20) o usar .format(Phone), pero un enfoque más seguro sería hacer que Python se encargue de codificar la cadena de consulta por usted.

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)

Es de esperar que sea más legible y disminuya las posibilidades de errores. Por ejemplo, en su pregunta, tiene % en lugar de %20 en %messaging.

2
Alasdair 13 ene. 2017 a las 16:40

Podrías intentar hacer este formato en su lugar:

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

La sustitución de cadena que está utilizando está desactualizada. Este puede ser un mejor enfoque para soluciones a largo plazo.

1
jape 13 ene. 2017 a las 16:34

¿Has probado esto?

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)

Está utilizando un formato desactualizado para la sustitución de cadenas. Y tampoco necesita form.save porque su formulario es una instancia, por lo que instance.save() sería suficiente.

1
Artem Bernatskyi 13 ene. 2017 a las 17:31