YOLO813

django制作站点地图sitemap(3)

    之前在django制作站点地图介绍了超过5万条站点地图如何制作,但是最近在做优化工作的时候发现有些问题,例如,我想同时建立CBA和NBA两个索引文件,所以按照上次的步骤键入了如下代码:

#urls.py    
path("Nba_sitemap.xml", views.index, {"sitemaps": Nba_sitemaps}),
path("Nba_<section>_sitemap.xml", views.sitemap, {"sitemaps": Nba_sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
path("Cba_sitemap.xml", views.index, {"sitemaps": Cba_sitemaps}),
path("Cba_<section>_sitemap.xml", views.sitemap, {"sitemaps": Cba_sitemaps}, name='django.contrib.sitemaps.views.sitemap'),

    结果发现无论访问的是Nba_sitemap.xml路径还是Cba_sitemap.xml路径,二者展现的页面索引均为同一种路径(<loc>中的路径格式,上文中为Cba_<section>_sitemap.xml),尽管可以很明显的看到二者提取的模型页数不一样(即数量/内容其实取到了正确的模型/表,但前面展示出来的路径会被后面覆盖掉),查阅了django.contrib.sitemaps.views源码,逐步排查,是因为sitemap_url_name参数的原因

#来源 from django.contrib.sitemaps import views

# 源代码
@x_robots_tag
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)

    sites = []  # all sections' sitemap URLs
    for section, site in sitemaps.items():
        # For each section label, add links of all pages of its sitemap
        # (usually generated by the `sitemap` view).
        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)
        # Add links to all pages of the sitemap.
        for page in range(2, site.paginator.num_pages + 1):
            sites.append('%s?p=%s' % (absolute_url, page))

    return TemplateResponse(request, template_name, {'sitemaps': sites},
                            content_type=content_type)

    因为时间关系,没有接着往下去研究了,因为我只是想要让站点地图文件展示正确的索引,干脆在站点地图xml文件中进行修改,直接说解决方案吧。

    使用sys模块找到python路径,在site-packages中的django模块找到contrib/sitemaps/templates文件夹下面的sitemap.xml和sitemap_index.xml(可以打开看看,里面的内容并不复杂),将这两份文件拷贝到Django的Templates目录下备用。

    新建过滤器sitemapProcess用于处理路径url,需要注意的是过滤器的第一个参数始终为其左边的值,而定义的链接b需始终位于url.py中的最后一行

# custom_filters.py
@register.filter("sitemapProcess")
def pro(value, country):
    a = country + "_sitemap"
    b = "cba_sitemap"
    x = value.replace(b, a)
    return x

    复制一份sitemap_index.xml文件,重命名为ball_sitemap_index.xml,键入如下代码,利用request获取路径中的参数,并将其作为变量pre_xml 传入到sitemapProcess过滤器中,进行替换:

# ball_sitemap_index.xml
<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{% load custom_filters %}
{% with request.path|cut:"_sitemap.xml"|cut:"/" as pre_xml %}
{% for location in sitemaps %}<sitemap>
<loc>{{location|sitemapProcess:pre_xml}}</loc>
<lastmod>{% now "Y-m-d\T00:00:00\Z" %}</lastmod>
</sitemap> {% endfor %}</sitemapindex>
{% endwith %}

    一般来讲,站点地图索引页链接都不会很多,所以替换起来也不会太影响性能。


    这种方法在我看来,有点low,后续再来改造。

 

 

更新:

    站点地图的问题,之前的做法实在是太low了,优化了一下。主要是将索引文件index和站点地图sitemap进行了分离,新建了一个all_sitemaps字典专门用于展现站点地图,这样后续再增加站点地图时,就很轻松了。

#urls.py
nba_index = {
    'nba': nbaSitemap,
}
nba_date_index = {
    'nba_date': DateOfnba,
}
cba_index = {
    'cba': cbaSitemap,
}
cba_date_index = {
    'cba_date': DateOfcba,
}
# 上方有多少section,这里就需要添加多少section
all_sitemaps={
    'nba': nbaSitemap,
    'nba_date':DateOfnba,
    'cba': cbaSitemap,
    'cba_date': DateOfcba,
}

urlpatterns = [
    # ---- views.index ----
    path("nba_sitemap.xml", views.index, {"sitemaps": nba_index}),
    path("nba_date_sitemap.xml", views.index, {"sitemaps": nba_date_index}),
    path("cba_sitemap.xml", views.index, {"sitemaps": cba_index}),
    path("cba_date_sitemap.xml", views.index, {"sitemaps": cba_date_index }),
    # ---- views.sitemaps ----
    path("<section>_sitemap.xml", views.sitemap, {"sitemaps": all_sitemaps}, name='django.contrib.sitemaps.views.sitemap'),
]

 

参阅:

https://docs.djangoproject.com/en/3.2/ref/contrib/sitemaps/
# 自制过滤器
https://mp.weixin.qq.com/s?__biz=MzU5OTEzOTM1Mg==&mid=2247483867&idx=1&sn=409d9678a730abb7d758409e4a1c4983&chksm=feb834acc9cfbdba2eef44e8aa509a4f93290108967841f7322ed91914e59061350f1470187c&token=485447628&lang=zh_CN#rd