【问题标题】:Decorating a sitemap view in Django在 Django 中装饰站点地图视图
【发布时间】:2015-06-25 11:29:27
【问题描述】:

我有几十万个网址,所以我想缓存我的站点地图。这会很好地生成站点地图:

from django.contrib.sitemaps import Sitemap, views as sitemap_views

class StuffSitemap(Sitemap):
    limit = 1000

    def items(self):
        return Stuff.objects.all().order_by('date')

urlpatterns = [
    ...,
    url(r'^sitemap\.xml$', sitemap_views.index, {'sitemaps': {'stuff': StuffSitemap()}}),
    url(r'^sitemap-(?P<section>.+)\.xml$', sitemap_views.sitemap, {'sitemaps': {'stuff': StuffSitemap()}}, name='django.contrib.sitemaps.views.sitemap'),
    ...
]

装饰sitemap.xml 索引视图效果很好(即使使用我自己的装饰器):

from django.views.decorators.cache import cache_control

url(r'^sitemap\.xml$', cache_control(max_age=3600, public=True)(sitemap_views.index), {'sitemaps': {'stuff': StuffSitemap()}}),

但是当我装饰实际的站点地图视图时,事情就开始崩溃了:

url(r'^sitemap-(?P<section>.+)\.xml$', cache_control(max_age=3600, public=True)(sitemap_views.sitemap), {'sitemaps': {'stuff': StuffSitemap()}}, name='django.contrib.sitemaps.views.sitemap')

这是完整的回溯:

Internal Server Error: /sitemap.xml
Traceback (most recent call last):
  File "/Users/blender/Projects/project/.venv/lib/python2.7/site-packages/django/core/handlers/base.py", line 104, in get_response
    response = middleware_method(request, callback, callback_args, callback_kwargs)
  File "/Users/blender/Projects/project/.venv/lib/python2.7/site-packages/debug_toolbar/middleware.py", line 77, in process_view
    response = panel.process_view(request, view_func, view_args, view_kwargs)
  File "/Users/blender/Projects/project/.venv/lib/python2.7/site-packages/debug_toolbar_line_profiler/panel.py", line 176, in process_view
    out = self.profiler.runcall(view_func, *args, **view_kwargs)
  File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/cProfile.py", line 149, in runcall
    return func(*args, **kw)
  File "/Users/blender/Projects/project/.venv/lib/python2.7/site-packages/django/contrib/sitemaps/views.py", line 17, in inner
    response = func(request, *args, **kwargs)
  File "/Users/blender/Projects/project/.venv/lib/python2.7/site-packages/django/contrib/sitemaps/views.py", line 37, in index
    sitemap_url_name, kwargs={'section': section})
  File "/Users/blender/Projects/project/.venv/lib/python2.7/site-packages/django/core/urlresolvers.py", line 551, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "/Users/blender/Projects/project/.venv/lib/python2.7/site-packages/django/core/urlresolvers.py", line 468, in _reverse_with_prefix
    (lookup_view_s, args, kwargs, len(patterns), patterns))
NoReverseMatch: Reverse for 'django.contrib.sitemaps.views.sitemap' with arguments '()' and keyword arguments '{'section': 'stuff'}' not found. 0 pattern(s) tried: []

奇怪的是,这两个视图在定义时都被修饰了:

def x_robots_tag(func):
    @wraps(func)
    def inner(request, *args, **kwargs):
        response = func(request, *args, **kwargs)
        response['X-Robots-Tag'] = 'noindex, noodp, noarchive'
        return response
    return inner


@x_robots_tag
def index(request, sitemaps,
          template_name='sitemap_index.xml', content_type='application/xml',
          sitemap_url_name='django.contrib.sitemaps.views.sitemap'):
    ....

在我看来,装饰器正在阻止 Django url 映射器正确处理已装饰的 sitemap 视图,因为它使用 **kwargs 而不是显式的 section kwarg:

sitemap_url = urlresolvers.reverse(sitemap_url_name, kwargs={'section': section})

但这并不能解释为什么它一开始就可以工作,因为视图已经被装饰了。有什么想法吗?

【问题讨论】:

  • 您是否尝试过更改将站点地图从django.contrib.sitemaps.views.sitemap 分离出来的网址名称?
  • @schillingt:是的。我补充说,当 Django 抛出错误时,它没有任何区别。
  • 您使用的是什么 django 版本?我用的是 1.4 也有同样的问题
  • @ark:我使用的是 1.7.8。我认为它存在于 1.8.0

标签: python django decorator sitemap


【解决方案1】:

我通过创建视图函数并返回内置的 django 站点地图视图来缓存我的站点地图:

from django.views.decorators.cache import cache_page
from django.contrib.sitemaps.views import sitemap


@cache_page(60*60*1)
def sitemap_view(request):
    return sitemap(request, sitemaps)

urlpatterns = [
    path('sitemap.xml', sitemap_view, name='django.contrib.sitemaps.views.sitemap')
]

【讨论】:

    猜你喜欢
    • 2012-08-02
    • 2018-02-12
    • 2018-10-18
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 2016-08-14
    • 2010-12-11
    • 1970-01-01
    相关资源
    最近更新 更多