2009-03-18 9 views
13

Supposons que j'ai un URLconf comme ci-dessous, et 'foo' et 'bar' sont des valeurs valides pour page_slug.Inverser les URL Django avec options supplémentaires

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

Puis, je pourrais reconstruire les URL en utilisant le ci-dessous, non?

>>> 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/' 

Mais que se passe-t-il si je change mon URLconf en cela?

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

Je me attendais à ce résultat:

>>> 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/' 

Cependant, ce renvoie une exception NoReverseMatch. Je soupçonne que j'essaie de faire quelque chose d'impossible. Des suggestions sur une façon plus saine d'accomplir ce que je veux?

Les URL nommées ne sont pas une option, car je ne veux pas que d'autres applications qui lient à celles-ci aient besoin de connaître les spécificités de la structure d'URL (encapsulation et tout ça).

+0

Que voulez-vous dire par "ne fonctionne pas"? Message d'erreur? Si oui, quoi? –

+0

Il déclenche une exception 'NoReverseMatch'. –

+0

S'il vous plaît mettre à jour la question avec de nouveaux faits - ne pas ajouter les informations utiles comme commentaires. –

Répondre

7

Voici ce que nous faisons.

urls.py a des motifs comme celui-ci

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

views.py que les appels inverse comme ce

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

Je ne pense pas que cela aide le problème de collision de noms. –

+0

À l'origine, je vous ai rabaissé à cause de ce que David a dit, mais il semble que vous répondiez à la question de Justin. Je pense toujours que la réponse de David est la "meilleure", mais la vôtre est une possibilité. – Tyson

+0

Peut-être que je n'ai pas compris comment cela s'appliquait à ce qui précède en première lecture. Je suppose qu'il semble que cela pourrait fonctionner ... mais seulement au prix de mettre une référence à un nom d'URL dans le niveau du modèle. Si object_1.datarealm.name = 'foo-direct' cela fonctionnera, si object_1.datarealm.name = 'foo', ce ne sera pas le cas. –

4

urls nommés doit être une option. Votre cas est mis en évidence dans la référence Django:

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

Je ne suis pas sûr que les concepteurs ont quitté un autre travail autour; ils s'attendaient à ce que les urls nommés le couvrent.

Puis-je digresser sur l'encapsulation? Merci. Il y a deux raisons principales:

  1. Abstraction - personne ne veut pour voir les détails
  2. sécurité - personne ne devrait voir les détails

Quant à 1, vous pouvez obtenir une quantité décente de kilométrage en python, et Django est un excellent exemple. Comme pour 2, c'est un langage interprété. Soit vous l'exécutez là où il est écrit, soit vous exportez des fichiers .pyc compilés. Si c'est vraiment ce que vous faites, alors compilez l'URL conf. Enfin, il semble moins encapsulé pour permettre aux autres applications de connaître les fonctions que la structure de l'URL. Mais si vous n'êtes pas vraiment d'accord, je pense que vous devrez mettre en place une méthode inverse plus flexible.

+0

D'accord; l'exportation d'URL nommées en tant qu'API est aussi "encapsulée" que l'exportation des noms de fonctions d'affichage. –

+1

# 2 - La sécurité dans l'obscurité? :( – monokrome

+0

Je pense que le lien est obsolète Quelle section voulez-vous faire un lien vers –

19

Vous devriez essayer de nommer vos URLs. Exemple:

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'), 
) 

Ensuite, il suffit d'éditer vos inverses et vous devriez le faire fonctionner.

>>> 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/' 

Plus d'infos sur: Django Docs

+0

Comment fonctionne exactement cette aide avec une URL comme dans la conf question:.?. (R '^ la page/(P *)/',' myapp.views.someview '),? – Rexford

Questions connexes