2010-04-17 4 views
4

J'ai une webapp qui liste tous mes artistes, albums et chansons quand le lien approprié est cliqué. Je fais un usage intensif des vues génériques (object_list/detail) et des urls nommées mais je rencontre un problème. J'ai trois modèles que de sortie à peu près le même HTML exact qui ressemblent à ceci:Django: URL nommées/même modèle, différente URL nommée

{% extends "base.html" %} 
{% block content %} 
<div id="content"> 

<ul id="starts-with"> 
{% for starts_with in starts_with_list %} 
    <li><a href="{% url song_list_x starts_with %}">{{ starts_with|upper }}</a></li> 
{% endfor %} 
</ul> 

<ul> 
{% for song in songs_list %} 
    <li>{{ song.title }}</li> 
{% endfor %} 
</ul> 

</div> 
{% endblock content %} 

Mon artiste et modèle album look à peu près la même chose et je voudrais combiner dans son trois modèle. Le fait que mes variables commencent par song peut facilement être changé à la valeur par défaut obj. C'est mon URL nommé <ul id="starts-with"> Je ne sais pas comment corriger. Évidemment, je veux qu'il soit lié à un album/artiste/chanson spécifique en utilisant les URLs nommés dans mon urls.py mais je ne sais pas comment le rendre sensible au contexte. Aucune suggestion?

urls.py:

urlpatterns = patterns('tlkmusic.apps.tlkmusic_base.views', 
    # (r'^$', index), 
    url(r'^artists/$', artist_list, name='artist_list'), 
    url(r'^artists/(?P<starts_with>\w)/$', artist_list, name='artist_list_x'), 
    url(r'^artist/(?P<artist_id>\d+)/$', artist_detail, name='artist_detail'), 
    url(r'^albums/$', album_list, name='album_list'), 
    url(r'^albums/(?P<starts_with>\w)/$', album_list, name='album_list_x'), 
    url(r'^album/(?P<album_id>\w)/$', album_detail, name='album_detail'), 
    url(r'^songs/$', song_list, name='song_list'), 
    url(r'^songs/(?P<starts_with>\w)/$', song_list, name='song_list_x'), 
    url(r'^song/(?P<song_id>\w)/$', song_detail, name='song_detail'), 
) 

Répondre

3

Vous pouvez définir des modèles d'URL pour un object_type générique plutôt qu'individuellement artistes, albums et chansons:

urlpatterns = patterns('tlkmusic.apps.tlkmusic_base.views', 
    # (r'^$', index), 
    url(r'^(?P<object_type>\w+)/$', music_object_list, name='music_object_list'), 
    url(r'^(?P<object_type>\w+)/(?P<starts_with>\w)/$', music_object_list, name='music_object_list_x'), 
    url(r'^(?P<object_type>\w+)/(?P<object_id>\d+)/$', music_object_detail, name='music_object_detail'), 

) 

Ensuite, dans votre modèle, votre balise url devient

{% url music_object_list_x object_type starts_with %} * 

vous pouvez vous trouver besoin d'un seul point de vue, music_object_list. Si vous trouvez que vous avez besoin de fonctions différentes pour chaque type d'objet, appelez les fonctions individuelles au music_object_list.

def music_object_list(request, object_type, starts_with=None): 
    if object_type == 'artists': 
     return artist_list(request, starts_with=starts_with) 
    elif object_type == 'albums': 
     return album_list(request, starts_with=starts_with) 
    ... 

Si vous utilisez django.views.generic.list_detail.object_list, alors souvenez-vous d'ajouter object_type au dictionnaire extra_context. Cela ajoutera object_type au contexte du modèle, permettant à la balise url de fonctionner.

extra_context = {'object_type': 'songs', ...} 

* Ceci est la nouvelle syntaxe de balise URL pour Django 1.2. Pour les versions plus anciennes, vous utiliseriez une virgule.

{% url music_object_list_x object_type,starts_with %} 

Voir pour plus d'informations

+1

J'aime où cela va les docs (Current, 1.1)! J'essaie de voir comment cela fonctionne en ce moment même. Si cela se passe comme prévu, je serai toujours reconnaissant. La seule chose que je changerais est l'utilisation de 'object_list' car le nom d'une fonction semble être en conflit avec' depuis django.views.generic.list_detail import object_list' mais cela est facilement surmonté. Je serai de retour avec mes découvertes! – TheLizardKing

+0

Bon point sur le conflit de nom. J'ai renommé la fonction en 'music_object_list'. – Alasdair

+0

Je pense que j'ai du mal à obtenir le {{% url music_object_list_x object_type, starts_with%} 'pour reconnaître le object_type dans mon template. Je suis sur Django 1.1.1 – TheLizardKing