Django: именованные URL / тот же шаблон, другой именованный URL - PullRequest
4 голосов
/ 18 апреля 2010

У меня есть веб-приложение, в котором перечислены все мои исполнители, альбомы и песни при нажатии на соответствующую ссылку. Я широко использую общие представления (object_list / detail) и именованные URL, но сталкиваюсь с раздражением. У меня есть три шаблона, которые в значительной степени выводят точно такой же HTML, который выглядит так:

{% 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 %}

Мой исполнитель и шаблон альбома выглядят примерно одинаково, и я хотел бы объединить три шаблона в один. Тот факт, что мои переменные начинаются с song, можно легко изменить на значение по умолчанию obj. Это мой <ul id="starts-with"> по имени URL, я не знаю, как исправить. Очевидно, я хочу, чтобы он ссылался на определенный альбом / исполнителя / песню, используя названные URL в моем urls.py, но я не знаю, как сделать это контекстным. Есть предложения?

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

1 Ответ

3 голосов
/ 18 апреля 2010

Вы можете определить шаблоны URL для универсального object_type вместо индивидуально для исполнителей, альбомов и песен:

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

)

Тогда в вашем шаблоне ваш URL-тег становится

{% url music_object_list_x object_type starts_with %} *

Вы можете обнаружить, что вам нужен только один просмотр, music_object_list. Если вы обнаружите, что вам нужны разные функции для каждого типа объекта, вызовите отдельные функции в 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)
     ...

Если вы используете django.views.generic.list_detail.object_list, не забудьте добавить object_type в словарь extra_context. Это добавит object_type в контекст шаблона, что позволит работать тегу url.

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

* Это новый синтаксис URL-тега для Django 1.2. Для более старых версий вы должны использовать запятую.

{% url music_object_list_x object_type,starts_with %}

См. Документы ( Ток , 1.1 ) для получения дополнительной информации

...