Django sitemap: 'module' object has no attribute 'values'
Asked Answered
S

2

8

I follow the description on the http://docs.djangoproject.com/en/1.2/ref/contrib/sitemaps/

I from django.contrib import sitemaps add this line

(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})

to URLconf

make file sitemap.py with:

from django.contrib.sitemaps import Sitemap
from blog.models import Post

class BlogSitemap(Sitemap):
    changefreq = 'monthly'
    priority = 0.5

    def items(self):
        return Post.objects.all()

    def lastmod(self, obj):
        return obj.date

at this address http://127.0.0.1:8000/sitemap.xml I get an error:

Traceback:
File "/usr/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  100.                     response = callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python2.7/site-packages/django/contrib/sitemaps/views.py" in sitemap
  33.         maps = sitemaps.values()

Exception Type: AttributeError at /sitemap.xml
Exception Value: 'module' object has no attribute 'values'

Anyone can help me?

Sihonn answered 14/2, 2011 at 19:2 Comment(2)
in your sitemaps/views.py comment maps = sitemaps.values() and print dir(sitemaps) ... tell us what it shows.Milium
['FlatPageSitemap', 'GenericSitemap', 'ImproperlyConfigured', 'PING_URL', 'Site', 'Sitemap', 'SitemapNotFound', 'builtins', 'doc', 'file', 'name', 'package', 'path', 'get_current_site', 'models', 'paginator', 'ping_google', 'urllib', 'urlresolvers', 'views']Sihonn
B
11

You missed a step - look at the example in the documentation.

Instead of importing the sitemaps module in your urls.py, import your BlogSitemap class, then create a sitemaps dictionary:

sitemaps = {'blog': BlogSitemap}
Brickey answered 14/2, 2011 at 19:24 Comment(1)
Then you didn't follow the instructions. Get rid of from django.contrib import sitemaps in urls.py, and use that instead.Brickey
A
11

I encountered this issue as well. Between the documentation and the code samples I was looking at, I still couldn't understand why I was seeing this error.

The misread documentation on my part was from https://docs.djangoproject.com/en/dev/ref/contrib/sitemaps/:

It may also map to an instance of a Sitemap class (e.g., BlogSitemap(some_var)).

I then looked at the Django source a bit closer. The view is as follows (django.contrib.sitemaps.views.sitemap):

def sitemap(request, sitemaps, section=None, template_name='sitemap.xml'):
    maps, urls = [], []
    if section is not None:
        if section not in sitemaps:
            raise Http404("No sitemap available for section: %r" % section)
        maps.append(sitemaps[section])
    else:
        maps = sitemaps.values()    # This is where I was seeing the error.
    page = request.GET.get("p", 1)
    current_site = get_current_site(request)
    for site in maps:
        try:
            if callable(site):
                urls.extend(site().get_urls(page=page, site=current_site))
            else:
                urls.extend(site.get_urls(page=page, site=current_site))
        except EmptyPage:
            raise Http404("Page %s empty" % page)
        except PageNotAnInteger:
            raise Http404("No page '%s'" % page)
    xml = smart_str(loader.render_to_string(template_name, {'urlset': urls}))
    return HttpResponse(xml, mimetype='application/xml')

It then dawned on me that the parameter sitemaps was actually a dictionary of key to sitemap objects, not a sitemap object itself. It's possible that this should have been obvious to me, but it took a bit for me to overcome my mental block.

The full coding sample that I used looks like the following:

sitemap.py file:

from django.contrib.sitemaps import Sitemap
from articles.models import Article

class BlogSitemap(Sitemap):
    changefreq = "never"
    priority = 0.5

    def items(self):
        return Article.objects.filter(is_active=True)

    def lastmod(self, obj):
        return obj.publish_date

urls.py file:

from sitemap import BlogSitemap

# a dictionary of sitemaps
sitemaps = {
    'blog': BlogSitemap,
}

urlpatterns += patterns ('',
    #...<snip out other url patterns>...
    (r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}),
)
Aquitaine answered 23/7, 2011 at 1:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.