Alterando a paginação padrão do Django sitemaps

O Django já conta com um aplicativo no contrib para gerar sitemaps, recentemente eu tive alguns problemas com o padrão de objetos por arquivo xml gerado que é de 50 mil por página. Como o sistema tinha certa de 120 mil objetos ficaria muito pesado essa consulta para o banco e também o tempo de renderização do template.

Investigando no código fonte do Django eu percebi como é montado o GenericSitemap :

# trechos do arquivo django/contrib/sitemaps/__init__.py
class Sitemap(object):
    # This limit is defined by Google. See the index documentation at
    # http://sitemaps.org/protocol.php#index.
    limit = 50000

    def __get(self, name, obj, default=None):
        try:
            attr = getattr(self, name)
        except AttributeError:
            return default
        if callable(attr):
            return attr(obj)
        return attr

    def items(self):
        return []

    def location(self, obj):
        return obj.get_absolute_url()

    def _get_paginator(self):
        if not hasattr(self, "_paginator"):
            self._paginator = paginator.Paginator(self.items(), self.limit)
        return self._paginator
    paginator = property(_get_paginator)

    def get_urls(self, page=1, site=None):
        if site is None:
            if Site._meta.installed:
                try:
                    site = Site.objects.get_current()
                except Site.DoesNotExist:
                    pass
            if site is None:
                raise ImproperlyConfigured("In order to use Sitemaps you must either use the sites framework or pass in a Site or RequestSite object in your view code.")

        urls = []
        for item in self.paginator.page(page).object_list:
            loc = "http://%s%s" % (site.domain, self.__get('location', item))
            priority = self.__get('priority', item, None)
            url_info = {
                'location':   loc,
                'lastmod':    self.__get('lastmod', item, None),
                'changefreq': self.__get('changefreq', item, None),
                'priority':   str(priority is not None and priority or '')
            }
            urls.append(url_info)
        return urls

class FlatPageSitemap(Sitemap):
    def items(self):
        current_site = Site.objects.get_current()
        return current_site.flatpage_set.filter(registration_required=False)

class GenericSitemap(Sitemap):
    priority = None
    changefreq = None

    def __init__(self, info_dict, priority=None, changefreq=None):
        self.queryset = info_dict['queryset']
        self.date_field = info_dict.get('date_field', None)
        self.priority = priority
        self.changefreq = changefreq

    def items(self):
        # Make sure to return a clone; we don't want premature evaluation.
        return self.queryset.filter()

    def lastmod(self, item):
        if self.date_field is not None:
            return getattr(item, self.date_field)
        return None

A solução é bastante simples:

from django.contrib.sitemaps import GenericSitemap
from django.conf import settings

SITEMAP_LIMIT = getattr(settings, 'SITEMAP_LIMIT', 2000)

class LimitedSitemap(GenericSitemap):
    limit = SITEMAP_LIMIT

Em primeiro lugar eu faço uso da variável SITEMAP_LIMIT que deve ser setada no settings.py, caso ela não esteja setada o valor 2000 é usado.

Depois crio uma classe chamada LimitedSitemap que herda de GenericSitemap e faço uso do limite para paginação. Com um limite de 2000 objetos a consulta ao banco ficou e a renderização do template ficaram bem mais leves.