this limit is defined by google see the index documentation at https www sitemaps orgprotocol htmlindex if protocol is none the urls in the sitemap will use the protocol with which the sitemap was requested enables generating urls for all languages override list of languages to use enables generating alternatehreflang links add an alternatehreflang link with value xdefault split the item langcode tuples again for the location priority lastmod and changefreq method calls languages for which this item is displayed return self languages def languagesself if self languages is not none return self languages return langcode for langcode in settings languages def itemsself if self i18n create item langcode tuples for all items and languages this is necessary to paginate with all languages already considered items item langcode for item in self items for langcode in self getlanguagesforitemitem return items return self items def locationself item forcelangcodenone if self i18n obj langcode item activate language from itemtuple or forced one before calling location with translation overrideforcelangcode or langcode return self getlocation item return self getlocation item property def paginatorself return paginator paginatorself items self limit def itemsself return def locationself item return item getabsoluteurl def getprotocolself protocolnone determine protocol return self protocol or protocol or https def getdomainself sitenone determine domain if site is none if djangoapps isinstalleddjango contrib sites site djangoapps getmodelsites site try site site objects getcurrent except site doesnotexist pass if site is none raise improperlyconfigured to use sitemaps either enable the sites framework or pass a siterequestsite object in your view return site domain def geturlsself page1 sitenone protocolnone protocol self getprotocolprotocol domain self getdomainsite return self urlspage protocol domain def getlatestlastmodself if not hasattrself lastmod return none if callableself lastmod try return maxself lastmoditem for item in self items defaultnone except typeerror return none else return self lastmod def urlsself page protocol domain urls latestlastmod none allitemslastmod true track if all items have a lastmod paginatorpage self paginator pagepage for item in paginatorpage objectlist loc fprotocol domainself locationitem priority self getpriority item lastmod self getlastmod item if allitemslastmod allitemslastmod lastmod is not none if allitemslastmod and latestlastmod is none or lastmod latestlastmod latestlastmod lastmod urlinfo item item location loc lastmod lastmod changefreq self getchangefreq item priority strpriority if priority is not none else alternates if self i18n and self alternates itemlanguages self getlanguagesforitemitem0 for langcode in itemlanguages loc fprotocol domainself locationitem langcode urlinfoalternates append location loc langcode langcode if self xdefault and settings languagecode in itemlanguages langcode settings languagecode loc fprotocol domainself locationitem langcode loc loc replaceflangcode 1 urlinfoalternates append location loc langcode xdefault urls appendurlinfo if allitemslastmod and latestlastmod self latestlastmod latestlastmod return urls class genericsitemapsitemap priority none changefreq none def initself infodict prioritynone changefreqnone protocolnone self queryset infodictqueryset self datefield infodict getdatefield self priority self priority or priority self changefreq self changefreq or changefreq self protocol self protocol or protocol def itemsself make sure to return a clone we don t want premature evaluation return self queryset filter def lastmodself item if self datefield is not none return getattritem self datefield return none def getlatestlastmodself if self datefield is not none return self queryset orderby self datefield valueslistself datefield flattrue first return none this limit is defined by google see the index documentation at https www sitemaps org protocol html index if protocol is none the urls in the sitemap will use the protocol with which the sitemap was requested enables generating urls for all languages override list of languages to use enables generating alternate hreflang links add an alternate hreflang link with value x default split the item lang_code tuples again for the location priority lastmod and changefreq method calls languages for which this item is displayed create item lang_code tuples for all items and languages this is necessary to paginate with all languages already considered activate language from item tuple or forced one before calling location determine protocol determine domain track if all items have a lastmod make sure to return a clone we don t want premature evaluation
from django.apps import apps as django_apps
from django.conf import settings
from django.core import paginator
from django.core.exceptions import ImproperlyConfigured
from django.utils import translation


class Sitemap:
    
    
    limit = 50000

    
    
    protocol = None

    
    i18n = False

    
    languages = None

    
    alternates = False

    
    x_default = False

    def _get(self, name, item, default=None):
        try:
            attr = getattr(self, name)
        except AttributeError:
            return default
        if callable(attr):
            if self.i18n:
                
                
                item, lang_code = item
            return attr(item)
        return attr

    def get_languages_for_item(self, item):
        
        return self._languages()

    def _languages(self):
        if self.languages is not None:
            return self.languages
        return [lang_code for lang_code, _ in settings.LANGUAGES]

    def _items(self):
        if self.i18n:
            
            
            items = [
                (item, lang_code)
                for item in self.items()
                for lang_code in self.get_languages_for_item(item)
            ]
            return items
        return self.items()

    def _location(self, item, force_lang_code=None):
        if self.i18n:
            obj, lang_code = item
            
            with translation.override(force_lang_code or lang_code):
                return self._get("location", item)
        return self._get("location", item)

    @property
    def paginator(self):
        return paginator.Paginator(self._items(), self.limit)

    def items(self):
        return []

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

    def get_protocol(self, protocol=None):
        
        return self.protocol or protocol or "https"

    def get_domain(self, site=None):
        
        if site is None:
            if django_apps.is_installed("django.contrib.sites"):
                Site = django_apps.get_model("sites.Site")
                try:
                    site = Site.objects.get_current()
                except Site.DoesNotExist:
                    pass
            if site is None:
                raise ImproperlyConfigured(
                    "To use sitemaps, either enable the sites framework or pass "
                    "a Site/RequestSite object in your view."
                )
        return site.domain

    def get_urls(self, page=1, site=None, protocol=None):
        protocol = self.get_protocol(protocol)
        domain = self.get_domain(site)
        return self._urls(page, protocol, domain)

    def get_latest_lastmod(self):
        if not hasattr(self, "lastmod"):
            return None
        if callable(self.lastmod):
            try:
                return max([self.lastmod(item) for item in self.items()], default=None)
            except TypeError:
                return None
        else:
            return self.lastmod

    def _urls(self, page, protocol, domain):
        urls = []
        latest_lastmod = None
        all_items_lastmod = True  

        paginator_page = self.paginator.page(page)
        for item in paginator_page.object_list:
            loc = f"{protocol}://{domain}{self._location(item)}"
            priority = self._get("priority", item)
            lastmod = self._get("lastmod", item)

            if all_items_lastmod:
                all_items_lastmod = lastmod is not None
                if all_items_lastmod and (
                    latest_lastmod is None or lastmod > latest_lastmod
                ):
                    latest_lastmod = lastmod

            url_info = {
                "item": item,
                "location": loc,
                "lastmod": lastmod,
                "changefreq": self._get("changefreq", item),
                "priority": str(priority if priority is not None else ""),
                "alternates": [],
            }

            if self.i18n and self.alternates:
                item_languages = self.get_languages_for_item(item[0])
                for lang_code in item_languages:
                    loc = f"{protocol}://{domain}{self._location(item, lang_code)}"
                    url_info["alternates"].append(
                        {
                            "location": loc,
                            "lang_code": lang_code,
                        }
                    )
                if self.x_default and settings.LANGUAGE_CODE in item_languages:
                    lang_code = settings.LANGUAGE_CODE
                    loc = f"{protocol}://{domain}{self._location(item, lang_code)}"
                    loc = loc.replace(f"/{lang_code}/", "/", 1)
                    url_info["alternates"].append(
                        {
                            "location": loc,
                            "lang_code": "x-default",
                        }
                    )

            urls.append(url_info)

        if all_items_lastmod and latest_lastmod:
            self.latest_lastmod = latest_lastmod

        return urls


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

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

    def items(self):
        
        return self.queryset.filter()

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

    def get_latest_lastmod(self):
        if self.date_field is not None:
            return (
                self.queryset.order_by("-" + self.date_field)
                .values_list(self.date_field, flat=True)
                .first()
            )
        return None