有一个 Web 应用可列出所有艺术家、专辑和歌曲,当单击合适的链接时。
- 广泛使用通用视图(对象列表/详情)和命名 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。 - 显然希望使用
urls.py
中的命名 URL 将其链接到特定的专辑/艺术家/歌曲,但不知道如何使它具有上下文感知。
- 解决方案:
方法一:
- 可以为通用
object_type
定义 URL 模式,而不是针对艺术家、专辑和歌曲分别定义:
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 命名为
artist-list
、album-list
和song-list
,如下所示:
urlpatterns = patterns('tlkmusic.apps.tlkmusic_base.views',
# (r'^$', index),
url(r'^artist/$', artist_list, name='artist-list'),
url(r'^artist/(?P<starts_with>\w)/$', artist_list, name='artist-list-x'),
url(r'^artist/(?P<artist_id>\d+)/$', artist_detail, name='artist-detail'),
url(r'^album/$', album_list, name='album-list'),
url(r'^album/(?P<starts_with>\w)/$', album_list, name='album-list-x'),
url(r'^album/(?P<album_id>\w)/$', album_detail, name='album-detail'),
url(r'^song/$', song_list, name='song-list'),
url(r'^song/(?P<starts_with>\w)/$', song_list, name='song-list-x'),
url(r'^song/(?P<song_id>\w)/$', song_detail, name='song-detail'),
)
- 在模板中,URL 标记将如下所示:
{% url "artist-list-x" starts_with %}
- 这是 Django 1.2 的新 URL 标记语法。对于较旧版本,需要使用逗号。
{% url "artist-list-x" starts_with, %}
有关更多信息,请参阅文档(Current,1.1)。