2009-03-18 21 views
13

Supongamos que tengo un URLconf como el siguiente, y 'foo' y 'bar' son valores válidos para page_slug.Invertir URL de Django con opciones adicionales

urlpatterns = patterns('', 
    (r'^page/(?P<page_slug>.*)/', 'myapp.views.someview'), 
) 

Entonces, podría reconstruir las URL usando el siguiente, ¿verdad?

>>> from django.core.urlresolvers import reverse 
>>> reverse('myapp.views.someview', kwargs={'page_slug': 'foo'}) 
'/page/foo/' 
>>> reverse('myapp.views.someview', kwargs={'page_slug': 'bar'}) 
'/page/bar/' 

¿Pero y si cambio mi URLconf a esto?

urlpatterns = patterns('', 
    (r'^foo-direct/', 'myapp.views.someview', {'page_slug': 'foo'}), 
    (r'^my-bar-page/', 'myapp.views.someview', {'page_slug': 'bar'}), 
) 

que esperaba este resultado:

>>> from django.core.urlresolvers import reverse 
>>> reverse('myapp.views.someview', kwargs={'page_slug': 'foo'}) 
'/foo-direct/' 
>>> reverse('myapp.views.someview', kwargs={'page_slug': 'bar'}) 
'/my-bar-page/' 

Sin embargo, esto produce una excepción NoReverseMatch. Sospecho que estoy tratando de hacer algo imposible. ¿Alguna sugerencia sobre una forma más sana de lograr lo que quiero?

Las URL con nombre no son una opción, ya que no quiero que otras aplicaciones que los enlazan tengan que conocer los detalles de la estructura de la URL (encapsulación y todo eso).

+0

¿Qué quiere decir con "no funciona"? ¿Mensaje de error? ¿Entonces qué? –

+0

Lanza una excepción 'NoReverseMatch'. –

+0

Actualice la pregunta con nuevos datos: no agregue la información útil como comentarios. –

Respuesta

7

Esto es lo que hacemos.

urls.py tiene patrones como éste

url(r'^(?P<datarealm>.*?)/json/someClass/(?P<object_id>.*?)/$', 'json_someClass_resource',), 

views.py como llamadas inversas como éste

object = SomeModel.objects.get(...) 
    url= reverse('json_someClass_resource', kwargs={'object_id':object.id,'datarealm':object.datarealm.name}) 
+0

No creo que eso ayude con el problema de colisión de nombres. –

+0

Originalmente te rechacé por lo que dijo David, pero parece que realmente respondes la pregunta de Justin. Sigo pensando que la respuesta de David es la "mejor", pero la tuya es una posibilidad. – Tyson

+0

Quizás no entendí cómo esto se aplica a lo anterior en la primera lectura. Supongo que parece que podría funcionar ... pero solo a costa de poner una referencia al nombre de una url en el nivel del modelo. Si object_1.datarealm.name = 'foo-direct' esto funcionará, si object_1.datarealm.name = 'foo', esto no lo hará. –

4

direcciones URL con nombre debe ser una opción. Su caso se pone de relieve en la referencia de Django:

http://docs.djangoproject.com/en/dev/topics/http/urls/?from=olddocs#id2

no estoy seguro de los diseñadores dejan otra solución alternativa; esperaban urls con nombre para cubrirlo.

¿Puedo hacer una digresión sobre la encapsulación? Gracias. Hay dos razones principales:

  1. Abstracción - nadie Quiere para ver los detalles
  2. Seguridad - nadie debe ver los detalles

En cuanto a 1, se puede obtener una cantidad decente de kilometraje en python, y Django es un excelente ejemplo. En cuanto a 2, es un lenguaje interpretado. O lo está ejecutando donde está escrito o está enviando archivos compilados .pyc. Si eso es lo que estás haciendo, compila la configuración de la URL.

Por último, parece menos encapsulado para que otras aplicaciones conozcan las funciones que la estructura de la url. Pero si realmente no está de acuerdo, creo que tendrá que implementar un método inverso más flexible usted mismo.

+0

De acuerdo; exportar URL con nombre como API está tan "encapsulado" como exportar nombres de funciones de vista. –

+1

# 2 - ¿Seguridad a través de la oscuridad? :( – monokrome

+0

Creo que el enlace está desactualizado. ¿A qué sección desea vincular? –

19

Debería intentar nombrar sus urlconfs. Ejemplo:

urlpatterns = patterns('', 
    url(r'^foo-direct/', 'myapp.views.someview', {'page_slug': 'foo'}, name='foo-direct'), 
    url(r'^my-bar-page/', 'myapp.views.someview', {'page_slug': 'bar'}, name='bar-page'), 
) 

Luego edite sus reveses y debe hacerlo funcionar.

>>> from django.core.urlresolvers import reverse 
>>> reverse('foo-direct', kwargs={'page_slug': 'foo'}) 
'/foo-direct/' 
>>> reverse('bar-page', kwargs={'page_slug': 'bar'}) 
'/my-bar-page/' 

Más información en: Django Docs

+0

¿Cómo ayuda esto exactamente con una configuración de URL como en la pregunta: (r '^ page/(? P . *)/',' myapp.views.someview '),? – Rexford

Cuestiones relacionadas