如何在Django中配置站点地图索引分页URL为/sitemap-products-3.xml格式
To get your sitemap pagination URLs working in the format /sitemap-products-3.xml instead of /sitemap-products.xml?p=3, follow these steps:
1. Fix the Sitemap Index Link Generation
First, adjust your custom index view to avoid modifying the original URL variable (which could cause unexpected behavior across iterations). Update the loop that generates paginated links:
def index(request, sitemaps, template_name='sitemap_index.xml', content_type='application/xml', sitemap_url_name='django.contrib.sitemaps.views.sitemap'): req_protocol = request.scheme req_site = get_current_site(request) sitemaps_lastmod = [] sites = [] for section, site in sitemaps.items(): if callable(site): site = site() protocol = req_protocol if site.protocol is None else site.protocol sitemap_url = reverse(sitemap_url_name, kwargs={'section': section}) absolute_url = '%s://%s%s' % (protocol, req_site.domain, sitemap_url) sites.append(absolute_url) sitemaps_lastmod.append(sitemaps[section].index_lastmod(sitemaps[section])) # Generate paginated links using a base URL to avoid modifying the original base_url = absolute_url.strip('.xml') for page in range(2, site.paginator.num_pages + 1): sites.append(f'{base_url}-{page}.xml') # Ensure lastmod entries match the number of sitemap URLs while len(sitemaps_lastmod) < len(sites): sitemaps_lastmod.append(sitemaps[section].index_lastmod(sitemaps[section])) sitez = zip(sites, sitemaps_lastmod) return render(request, template_name, {'sitemaps': sitez}, content_type=content_type)
2. Create a Custom Sitemap View
The default Django sitemap view reads the page number from the query string (p parameter). We need a custom view that accepts the page number from the URL path instead:
from django.contrib.sitemaps.views import sitemap as original_sitemap from django.http import Http404 def custom_sitemap(request, section=None, page=None, **kwargs): # Handle page number from URL path if page is not None: try: page_num = int(page) if page_num < 1: raise ValueError except (TypeError, ValueError): raise Http404("Invalid page number") # Pass the page number to the original view via modified request.GET request.GET = request.GET.copy() request.GET['p'] = page_num return original_sitemap(request, section=section, **kwargs)
3. Update URLs Configuration
Add URL patterns to handle both the first page of each sitemap (without a page number) and the paginated pages. Make sure to use your custom sitemap view and update the sitemap URL name in the index view:
from django.contrib.sitemaps.views import index from .views import custom_sitemap, index as custom_index # Your sitemap definitions sitemaps_pages = { 'products': YourProductSitemap, # Add other sitemap sections here } urlpatterns = [ # Sitemap index page path('sitemap.xml', custom_index, { 'sitemaps': sitemaps_pages, 'sitemap_url_name': 'custom_sitemap' # Use the name of your first sitemap URL pattern }), # First page of each sitemap section path('sitemap-<section>.xml', custom_sitemap, { 'sitemaps': sitemaps_pages }, name='custom_sitemap'), # Paginated sitemap pages (e.g., /sitemap-products-3.xml) path('sitemap-<section>-<int:page>.xml', custom_sitemap, { 'sitemaps': sitemaps_pages }, name='custom_sitemap_paginated'), ]
How It Works
- The custom
indexview generates clean paginated URLs like/sitemap-products-3.xmlinstead of using query parameters. - The
custom_sitemapview takes the page number from the URL path, validates it, and passes it to Django's original sitemap view via thepquery parameter (so we reuse all of Django's existing sitemap logic). - The URL patterns capture both the base sitemap URLs and the paginated versions, directing them to the custom view.
This setup will resolve the 404 errors and serve your sitemap pages at the clean URL format you want.
内容的提问来源于stack exchange,提问作者allldo

