2011-05-28 29 views
7

Tengo problemas para enviar más de una variable a la vista.Obteniendo dos cadenas en la variable de la URL en Django

mi urls.py es el siguiente:

urlpatterns = patterns('', 
    url(r'^rss/(?P<anything>[^/]+)/$', 'rss.rssama.views.makerss', name='anything'), 
    url(r'^$', 'rss.rssama.views.home'),  
) 

views.py

def maakrss(request, anything): 

Así que ahora lleva desde www.mydomain.com/rss/[anything]/ y envía 'nada 'a mi vista. Sin embargo, también quieres que se envíe junto a otra cadena views.py, como:

www.mydomain.com/rss/[anynumber]/[anystring]/

yo probamos este, pero que no funcionó :

url(r'^rss/(?P<anynumber>[^/]+)/(?P<anystring>[^/]+)/$', 'rss.rssama.views.makerss', name='anynumber', name2='anystring'), 

Pero esto no funciona, da este error: argumento de palabra clave repetida (urls.py, línea 17)

Así que mi pregunta: ¿Cómo puedo llegar a dar a lo largo de dos cuerdas de la url?

Respuesta

26

Para empezar, la parte de expresiones regulares debería tener este aspecto:

r'^/rss/(?P<anynumber>\d+)/(?P<anystring>.+)/$' 

Esas cadenas dentro de las partes <...> le permiten dar un nombre a lo que los partidos de expresiones regulares. Django usará ese nombre para pasar el valor a su función. Por lo tanto, su función debe tener un argumento con el mismo nombre. En este caso, Django tomará el valor llamado anynumber y usará ese valor para el parámetro de su función que se llama anynumber. Lo mismo ocurre con anystring, y este sistema lo libera de preocuparse por el orden en que están los argumentos de su función.

\d+ coincidirá con uno o más caracteres numéricos (dígitos). Es una buena práctica limitar la expresión regular para que coincida solo con los números, si es eso lo que intenta atrapar, en lugar de cualquier personaje, y esperar que solo aparezcan los números. Si desea limitar la parte de los dígitos a una cierta cantidad de dígitos, puede usar \d{1,4} para tomar de uno a cuatro dígitos.

La siguiente parte, (?P<anystring>.+) capturará una cadena que consta de uno o más de los caracteres. Esto realmente coincidiría con algo como 'letters/moreletters', incluida la barra oblicua. Hay una serie de "secuencias especiales" en Python regex que pueden ayudar. Para hacer coincidir solo dígitos, letras y el guión bajo, use \w, como en (?P<anystring>\w+). Para ser más laxo pero ignorar el espacio en blanco o cualquier otro sin sentido, (?P<anystring>[a-zA-Z1-9:;_{}\[\]] para atrapar una gran cantidad de caracteres. Asegúrate de escapar de todo lo que pueda ser un personaje especial en una expresión regular. Sin embargo, sé conservador. Si permite demasiadas opciones, quién sabe qué tipo de errores tendrá que resolver más tarde.

Ahora sobre parámetro de nombre de la función url. Ese nombre no es lo que pasará los patrones capturados a sus funciones como. Es un nombre para una clase particular de invocación de su función de vista que se puede usar como abreviado en otros contextos, como la etiqueta de plantilla {% url view-name arg1 arg2 %}. Entonces, el nombre que ya tiene, "cualquier cosa", se refiere a una llamada a su función de vista, pasándole un argumento de palabra clave que se llama cualquier cosa. Para el caso en el que quiera pasar dos cadenas, déle un nombre como "rss-number-string" para indicar los argumentos que desea tomar, o un nombre que haga referencia a la función especial que su vista realizará con esa combinación.

que usar varios nombres para la misma función todo el tiempo, y la clave es la siguiente:

def makerss(request, anystring=None, anynumber=None): 

Al dar a los valores de los parámetros por defecto, que le permite utilizar la misma función de diferentes maneras. En este caso, la función se puede utilizar cuando sólo desea pasar un valor de anystring, o cuando anystringanynumber y debe tener valores.

Sé que este es un montón de puntos diferentes, así que trataré de ponerlo todo junto para que pueda ver cómo podría funcionar. Para tener dos direcciones URL, una que coger una cuerda y se lo pasa, y otro que coge un número, una barra, y luego una cadena, pero ambos apuntan a la misma función de vista, se puede usar esto:

urlpatterns = patterns('', 
    url(r'^rss/(?P<anystring>\w+)/$', 'rss.rssama.views.makerss', name='rss-anystring'), 
    url(r'^rss/(?P<anynumber>\d+)/(?P<anystring>\w+)/$', 'rss.rssama.views.makerss', name='rss-number-string'), 
    url(r'^$', 'rss.rssama.views.home'),  
) 

Con una función de vista algo como esto:

def makerss(request, anystring=None, anynumber=None): 
    if anystring: 
     if anynumber: 
      #Do something with the string and the number 
     else: 
      #Do something with just the string 

Por favor, hágamelo saber si esto ayuda. Además, Django rockea, ¡así que felicitaciones!

Python Regex Library Docs

+1

Kevin, ¡muchas gracias por su explicación detallada! ¡Realmente aprecio el tiempo que tomó para explicar las cosas completamente! ¡Funciona como un encanto ahora! PD. Después de pensar mucho sobre qué aprender (PHP y algo de framework o Django, tenía habilidades básicas de php y python), decidí ir con Django porque me gustaba tanto Python. A pesar de que tienes que aprender un poco al principio, ¡me gusta mucho hasta ahora! – Javaaaa

+0

De nada. Estaré encantado de hacer mi mejor esfuerzo en cualquier otra pregunta que publique. –

1

No necesita dar dos argumentos de nombre para esto. Quiero decir, ya tienes los nombres de las variables dentro de Regex. El problema real es, no se puede dar dos argumentos de nombre, por lo que se puede hacer esto en su lugar:

url(r'^rss/(?P<anynumber>[^/]+)/(?P<anystring>[^/]+)/$', 'rss.rssama.views.makerss',name='something'), 

EDIT:

usando el URLconf anterior puede crear vista correspondiente como:

def makerss(request, anynumber, anystring): 
+0

y cómo puedo acceder a estas dos variables en los puntos de vista, entonces? Ahora obtengo el error: función ... obtengo un argumento de palabra clave inesperado 'anynumber' cuando uso algo [0] para obtener el contenido anynumber. – Javaaaa

+0

¿Qué? Realmente necesitas leer la documentación. 'algo' no se pasa a la vista, 'anynumber' y 'anystring' son. –

+0

Edité la publicación – Hgeg

0

¿Qué se supone que es name2? La función url toma un parámetro name, que es el nombre de la URL cuando la invierte, pero no puede poner funciones adicionales aleatorias.

De lo contrario, tiene la sintaxis correcta para enviar dos elementos a una vista. Por supuesto, ya que ha enmascarado los nombres de las variables y no ha proporcionado el error o rastreo real, no tenemos forma de saber qué es lo que realmente está fallando.

Cuestiones relacionadas