Django URL 排序

1 投票
3 回答
2522 浏览
提问于 2025-04-20 02:00

我正在尝试使用Django的站点地图框架来设置一个站点地图,但在设置站点地图的URL时遇到了问题。

这是我项目中的urls.py文件

from django.contrib.sitemaps.views import sitemap

if settings.DEBUG:
    import debug_toolbar
    urlpatterns = patterns('',
        url(r'^debug-toolbar/', include(debug_toolbar.urls)),
    )

    urlpatterns += patterns('',
        url(r'^admin/', include(admin.site.urls)),
        url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps}),
        url(r'^robots\.txt$', TemplateView.as_view(template_name="robots.txt")),
        url(r'^500/$', TemplateView.as_view(template_name="500.html")),
        url(r'^404/$', TemplateView.as_view(template_name="404.html")),
        url(r'^', include('hunt.urls')),
    )
else:
    urlpatterns = patterns('',
        url(r'^admin/', include(admin.site.urls)),
        url(r'^sitemap\.xml$', sitemap, {'sitemaps': sitemaps}),
        url(r'^robots\.txt$', TemplateView.as_view(template_name="robots.txt")),
        url(r'^500/$', TemplateView.as_view(template_name="500.html")),
        url(r'^404/$', TemplateView.as_view(template_name="404.html")),
        url(r'^', include('hunt.urls')),
    )

这是我hunt应用中的urls.py文件

urlpatterns = patterns('hunt.views',
    url(r'^$', top100, name='top100'),
    url(r'^explore/$', explore, name='explore'),
    url(r'^monthly/$', monthlytop10, name='monthlytop10'),
    url(r'^trending/$', trending, name='trending'),
    url(r'^genres/$', genres, name='genres'),
    url(r'^genres/(?P<slug>.+)/$', genre_view, name='genre_view'),
    url(r'^contact/$', contact, name='contact'),
    url(r'^contact/thanks/$', thanks, name='thanks'),
    url(r'^faq/$', faq, name='faq'),
    url(r'^songs/(?P<slug>.+)$', song_search, name='song_search'),
    url(r'^loadmore/dj/$', loadmore_dj, name='loadmore_dj'),
    url(r'^loadmore/genre/$', loadmore_genre, name='loadmore_genre'),
    url(r'^loadmore/month/$', loadmore_month, name='loadmore_month'),
    url(r'^loadmore/trending/$', loadmore_trending, name='loadmore_trending'),
    url(r'^vote/dj/$', vote_dj, name='vote_dj'),
    url(r'^vote/genre/$', vote_genre, name='vote_genre'),
    url(r'^vote/month/$', vote_month, name='vote_month'),
    url(r'^vote/trending/$', vote_trending, name='vote_trending'),
    url(r'^(?P<slug>.+)/$', dj, name='dj'),
)

urlpatterns += staticfiles_urlpatterns()
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

当我尝试访问sitemap.xml时,出现了一个错误

404 Page Not Found
No DJ matches the given query.

这意味着它试图访问我hunt应用中的最后一个URL。为什么它会尝试访问DJ页面,即使这个页面在sitemap.xml的URL之后呢?

编辑 - 根据eran的建议,我运行了django_extensions中的show_urls命令。以下是输出结果

/   hunt.views.top100   top100
/404/   django.views.generic.base.TemplateView
/500/   django.views.generic.base.TemplateView
/<slug>/    hunt.views.dj   dj
/contact/   hunt.views.contact  contact
/contact/thanks/    hunt.views.thanks   thanks
/explore/   hunt.views.explore  explore
/faq/   hunt.views.faq  faq
/genres/    hunt.views.genres   genres
/genres/<slug>/ hunt.views.genre_view   genre_view
/loadmore/dj/   hunt.views.loadmore_dj  loadmore_dj
/loadmore/genre/    hunt.views.loadmore_genre   loadmore_genre
/loadmore/month/    hunt.views.loadmore_month   loadmore_month
/loadmore/trending/ hunt.views.loadmore_trending    loadmore_trending
/media/<path>   django.views.static.serve
/monthly/   hunt.views.monthlytop10 monthlytop10
/robots.txt django.views.generic.base.TemplateView
/sitemap.xml    django.contrib.sitemaps.views.sitemap
/songs/<slug>   hunt.views.song_search  song_search
/static/<path>  django.contrib.staticfiles.views.serve
/trending/  hunt.views.trending trending
/vote/dj/   hunt.views.vote_dj  vote_dj
/vote/genre/    hunt.views.vote_genre   vote_genre
/vote/month/    hunt.views.vote_month   vote_month
/vote/trending/ hunt.views.vote_trending    vote_trending

3 个回答

0

我注意到你的网站地图和robots.txt的链接是唯一没有结尾斜杠的。很多网络服务器会把 myurl.com/item 自动重定向到 myurl.com/item/。比如说,这在使用Apache服务器时是一个推荐的做法(你可以搜索一下“结尾斜杠问题”)。你可以试着用curl命令访问没有结尾斜杠的链接,看看是否会得到一个301重定向。如果是这样的话,说明它可能会重定向到那个带有结尾斜杠的链接,而这个链接在你的urls.py文件中没有匹配到。你可以尝试在你的正则表达式中加上结尾斜杠,或者在settings.py文件中设置 APPEND_SLASH = True

1

根据这个show_urls的输出,hunt.views.dj的URL模式优先级更高,因为r'^(?P<slug>.+)/$'这个正则表达式出现在sitemap.xml的正则表达式之前。前面的正则表达式会匹配到请求"sitemap.xml",所以Django根本不会去匹配专门为sitemap.xml设置的模式。这样一来,它也不会匹配到/contact/、/explore/、/faq/等其他路径。

我猜这是因为你的项目中的urls.py是通过追加的方式来添加urlpatterns("urlpatterns +="),而不是直接设置它。看起来你没有把项目中的urls.py里的所有导入都粘贴过来,但我猜其中有一个导入了patterns对象;否则在导入时你会遇到NameErrorname 'patterns' is not defined)的错误。

你可以通过把这个...

urlpatterns += patterns('',

...改成这个...

urlpatterns = patterns('',

来解决这个问题。不过我不能确定,因为我不知道你在项目的urls.py里还导入了什么。

0

我之前在我的模板文件夹里有一个叫 sitemaps.xml 的文件。删除这个文件后,问题就解决了。

撰写回答