2010-01-22 15 views
21

En mi urls.py tengo:Django - Cómo pasar varios argumentos para la etiqueta de plantilla url

(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/section/(?P<slug>[-\w]+)/$', 
    'paper.views.issue_section_detail', 
    {}, 
    'paper_issue_section_detail' 
), 

y estoy tratando de hacer esto en una plantilla:

{% url paper_issue_section_detail issue.pub_date.year,issue.pub_date.month,issue.pub_date.day,section_li.slug %} 

pero Obtengo este error:

TemplateSyntaxError 
Caught an exception while rendering: Reverse for 'paper_issue_section_detail' with arguments '(2010, 1, 22, u'business')' and keyword arguments '{}' not found. 

Sin embargo, si cambio el patrón de URL para que solo requiera un único argumento, funciona bien. es decir:

(r'^(?P<year>\d{4})/$', 
    'paper.views.issue_section_detail', 
    {}, 
    'paper_issue_section_detail' 
), 

y:

{% url paper_issue_section_detail issue.pub_date.year %} 

por lo que parece a quejarse cuando pase más de un solo argumento utilizando la etiqueta de plantilla 'url' - Me sale el mismo error con dos argumentos. ¿Hay una manera diferente de pasar varios argumentos? Intenté pasar argumentos de palabra clave y eso genera un error similar.

Por lo que vale la pena, la vista relacionada comienza así:

def issue_section_detail(request, year, month, day, slug): 

¿Cómo puedo pasar más de un solo argumento a la etiqueta de plantilla url?

Respuesta

8

El problema reside en la parte /(?P<month>\d{2})/ de su configuración de url. Solo permite exactamente dos dígitos (\d{2}), mientras que issue.pub_date.month tiene solo un dígito.

Puede permitir también un dígito en la URL (pero esto violará el principio de URL únicas, /2010/1/... sería lo mismo que /2010/01/...) o pasar dos dígitos al argumento de mes en su plantilla de URL.
Puede usar el filtro date para lograr un formato uniforme de los objetos de fecha. Utilice la etiqueta del URL como esta:

{% url paper_issue_section_detail issue.pub_date|date:"Y",issue.pub_date|date:"m",issue.pub_date|date:"d",section_li.slug %} 

Mira el argumento de mes y día: Se muestra siempre como dos dígitos (con un cero si es necesario). Eche un vistazo al documentation of the now tag para ver qué opciones son posibles para el filtro date.

+0

Eso suena genial, realmente no quiero cambiar el formato posible de la URL. Pero cuando hago issue.pub_date.month | date: "m", se pasa una cadena vacía a la URL/vista. –

+1

Tienes razón, lo siento. Obviamente me equivoqué en la publicación original. Corregí la etiqueta 'url'. Debe usar 'issue.pub_date | date:" m "' en lugar de 'issue.pub_date.month | date:" m "'. El filtro 'date' opera en objetos' datetime' (el atributo pub_date) y no en enteros (el atributo pub_date.month). –

+0

Doh, por supuesto, debería haberlo visto también. Gracias por la ayuda de Gregor. –

5

Su expresión mensual es (?P<month>\d{2}), pero le está enviando el argumento 1. El 1 no coincide con \d{2}, por lo que el url resolver no encuentra su vista.

Intente cambiar la expresión de mes a \d{1,2} (o algo por el estilo).

+0

Gracias mucho por su sugerencia Seth - yo no había hecho la conexión entre la expresión regular y lo que estaba tratando de pasar a ella. Pero no quería aflojar la restricción en la URL, así que ahora estoy cambiando el formato de lo que paso, usando la sugerencia de Gregor Müllegger. –

12

Tuve el mismo problema (estoy usando Django 1.3.1) y tratado sugerencia de Gregor Müllegger, pero eso no funcionó por dos razones:

  • no debe haber comas entre año, mes y día valores
  • mi punto de vista genérico basado en clases parece tomar sólo de palabras clave argumentos

por lo tanto la única solución de trabajo fue:

{% url news_detail slug=object.slug year=object.date|date:"Y" month=object.date|date:"m" day=object.date|date:"d" %} 
Cuestiones relacionadas