【问题标题】:Django: Named URLs / Same Template, Different Named URLDjango:命名 URL / 相同模板,不同命名 URL
【发布时间】:2010-04-17 23:02:45
【问题描述】:

我有一个网络应用程序,当点击相应的链接时,它会列出我所有的艺术家、专辑和歌曲。我广泛使用通用视图(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。这是我的&lt;ul id="starts-with"&gt; 命名网址,我不知道如何更正。显然,我希望它使用我的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'),
)

【问题讨论】:

    标签: python django django-templates


    【解决方案1】:

    您可以为通用 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', ...}
    

    * 这是 Django 1.2 的新 url 标签语法。对于旧版本,您可以使用逗号。

    {% url music_object_list_x object_type,starts_with %}
    

    有关详细信息,请参阅文档(Current1.1

    【讨论】:

    • 我喜欢这里的发展方向!我正试图在我们说话时看看这是如何工作的。如果这按计划进行,我将永远感激不尽。我唯一要改变的是使用object_list 作为函数名似乎与from django.views.generic.list_detail import object_list 冲突,但这很容易克服。我会带着我的发现回来的!
    • 关于名称冲突的要点。我已将该函数重命名为music_object_list
    • 我想我很难让 {% url music_object_list_x object_type,starts_with %} 识别模板中的 object_type。我在 Django 1.1.1
    • 哈哈,哎呀。我应该添加我的观点,但我通过我的 extra_context = {'starts_with_list': starts_with_list, 'object_type': 'songs'} 传递它来修复它
    • 不客气。我更新了我的答案,提到将object_type 添加到extra_context,但我看到你已经解决了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-12
    • 2010-11-08
    • 2016-04-15
    • 2020-07-13
    • 2015-02-14
    • 2012-07-18
    • 2011-08-18
    相关资源
    最近更新 更多