2009-08-30 50 views
25

¿Puede alguien explicar cómo se puede escribir un patrón de URL y ver que permite los parámetros opcionales? Lo he hecho con éxito, pero siempre rompo la etiqueta de la plantilla de URL.Parámetros de obtención opcionales en django?

Esto es lo que tengo actualmente:

Patrón

(r'^so/(?P<required>\d+)/?(?P<optional>(.*))/?$', 'myapp.so') 

Ver

def so(request, required, optional): 

Si utilizo la etiqueta plantilla de URL en este ejemplo proporcionando ambos argumentos, funciona está bien; sin embargo, si omito el argumento opcional, obtengo un error de inversión.

¿Cómo puedo lograr esto?

Gracias, Pete

+1

Está en la hoja de ruta para 1.3: http://code.djangoproject.com/ticket/14772 –

Respuesta

37

general que hacer dos patrones con un named url:

url(r'^so/(?P<required>\d+)/$', 'myapp.so', name='something'), 
url(r'^so/(?P<required>\d+)/(?P<optional>.*)/$', 'myapp.so', name='something_else'), 
+2

Sí, esta es la forma habitual de hacerlo. El inversor de URL tiene poca inteligencia acerca de las expresiones regulares (no implementa un analizador de expresiones regulares completo), y no puede manejar partes opcionales. Usted es libre de usar todo el poder de las expresiones regulares en sus patrones de URL, pero luego renuncia a la inversión de URL. –

+0

Gracias, esto es lo que estaba buscando. Me sorprendió saber que necesitaba dos URL separadas. – slypete

+9

Buena respuesta. Pero un poco deprimente ... – Joe

1

por qué no tener dos patrones:

(r'^so/(?P<required>\d+)/(?P<optional>.*)/$', view='myapp.so', name='optional'), 
(r'^so/(?P<required>\d+)/$', view='myapp.so', kwargs={'optional':None}, name='required'), 
+0

No importa en qué orden ponga estos patrones de URL. Ambos están limitados con $ al final, por lo que no puede haber ambigüedad.Hay, por supuesto, situaciones similares en las que importaría (si el patrón más corto no tuviera límites, por ejemplo). –

+0

Hmmmm. Editaré – hughdbrown

5

Otros han demostrado la manera de manejar esto con dos patrones de URL nombrados por separado. Si la repetición de parte del patrón de URL le molesta, es posible deshacerse de él mediante el uso de include():

url(r'^so/(?P<required>\d+)/', include('myapp.required_urls')) 

y luego añadir un archivo con required_urls.py:

url(r'^$', 'myapp.so', name='something') 
url(r'^(?P<optional>.+)/$', 'myapp.so', name='something_else') 

Normalmente No consideraría que esto valga la pena a menos que haya un prefijo común para un buen número de URL (sin duda, más de dos).

+0

Gracias Carl, parece que también será útil. – slypete

+0

puede usar 'patterns' para guardar tener que crear un nuevo archivo:' url (r '...', include (patterns ('', url (...), url (...)))) ' . [Ver aquí] (https://docs.djangoproject.com/en/dev/topics/http/urls/#including-other-urlconfs) – Patrick

-1

en views.py haces algo simple.

def so(request, required, optional=None): 

Y cuando no te dan parámetro opcional en la cadena URL será Ninguno en el código.

+0

¿En qué versión de Django funciona? He 1.5 esto no funciona sin cambios en url.py –

+0

Esto funciona para los métodos views.py. Y está bastante depreciado ya que Django cambió muchas cosas en términos de administración de URL y aplicación de vistas. [p.ej. Vistas basadas en clases]; – Popara

+0

No puede hacer eso en django, primero mira 'url.py' y no encontrará ningún patrón que coincida con la url. Como esto está en 'views.py' y no se ejecutará hasta después de que se encuentre un patrón –

17

URL sencillas y elegantes :) Django son polimórficos:

url(r'^so/(?P<required>\d+)/$', 'myapp.so', name='sample_view'), 
url(r'^so/(?P<required>\d+)/(?P<optional>.*)/$', 'myapp.so', name='sample_view'), 

su obious que usted tiene que hacer que sus puntos de vista como esto:

def sample_view(request, required, optional = None): 

así se le puede llamar con el mismo nombre y funcionaría el trabajo url resolver bien.Sin embargo tenga en cuenta que usted no puede pasar Ninguno como el argumento necesario y esperar que se llega a la expresión regular y sin argumento:

incorrecto:

{% url sample_view required optional %} 

correcta:

{% if optional %} 
    {% url sample_view required optional %} 
{% else %} 
    {% url sample_view required %} 
{% endif %} 

No sé si esto está documentado en alguna parte, lo he descubierto por accidente. Olvidé volver a escribir los nombres de la url y funcionaba de todos modos :)

1

Para cualquier persona que todavía tenga este problema. Uso Django 1.5 (actualizado: usando 1.8) y sigue funcionando bien.

que utilizo:

urls.py

url(r'^(?P<app_id>\d+)/start/+(?P<server_id>\d+)?', views.restart, name='restart') 

Luego, cuando yo quiero tener las dos direcciones URL

/1/start/2 

y

/1/start 

Yo uso:

{% url '<namespace>:start' app.id %} 
{% url '<namespace>:start' app.id server.id %} 

Esto creará las direcciones URL

/1/start/2 and 
/1/start/ <- notice the slash. 

Si crear una URL manualmente que tiene que mantener el/en mente.

I hoop esto ayuda a cualquier persona!

-2

Dependiendo de su caso de uso, simplemente se puede desear para pasar un parámetro URL de este modo:

url/?parameter=foo 

llamada esta en su punto de vista:

request.REQUEST.get('parameter') 

esto devolverá 'foo'

+0

Mi pregunta fue sobre pasar el parámetro opcional a la función de vista y usarlo con la etiqueta de plantilla de url. – slypete

Cuestiones relacionadas