【问题标题】:How to tell Django to put media (pdf) files urls in sitemap.xml?如何告诉 Django 将媒体(pdf)文件 url 放入 sitemap.xml?
【发布时间】:2016-07-07 16:36:52
【问题描述】:

我已将静态视图和模型视图放入 Django 生成的 sitemap.xml 文件中,但我不知道如何告诉 Django 将所有媒体文件放入其中?我有一百个带有 seo 友好链接的 PDF 文件,我希望它们在我的 sitemap.xml 中,但由于它们与我的任何模型都不相关,我不知道如何管理它?

编辑:我几乎忘记了一件重要的事情 - 我的媒体 (pdf) 文件是通过 CloudFront 提供的,所以即使我设法在我的 Django Sitemap.xml 中列出它们,我也会遇到其他问题,因为它们有 'something.cloudfront .com' 在他们的 url 中,而不是在我的网站的 url 'example.com' 中。 这甚至可以解决吗?这对 SEO 有何影响?

已解决: @kb,感谢您的出色回答!正如您在答案的第一部分中建议的那样,我已经在我的 htaccess 中使用了 RewriteRule,它工作正常。 从第二部分开始,而不是为我的媒体文件创建模型(这可以正常工作,但唯一的缺点是手动添加每个新的 pdf 文件) 我决定在我的 items() 方法中添加一些行,以便我可以列出存储桶内容并过滤 pdf 文件。有了它,我可以轻松地随时更新我的​​所有文件:

#sitemap.py
import boto
from boto.s3.key import Key
from boto.s3.connection import S3Connection
import re

def items(self):    
        AWS_ACCESS_KEY_ID = #'my_access_key_number'
        AWS_SECRET_ACCESS_KEY = #'my_secret_access_key'
        Bucketname = #'my_bucket_name'
        conn = boto.s3.connect_to_region('eu-central-1', aws_access_key_id=AWS_ACCESS_KEY_ID, aws_secret_access_key=AWS_SECRET_ACCESS_KEY, is_secure=False, calling_format = boto.s3.connection.OrdinaryCallingFormat())
        bucket = conn.get_bucket(Bucketname)
        new_list = []
        regex = re.compile(r'bucketsubfolder/media.*\.pdf$', re.I) #i hold my media files in bucketsubfolder so url is for example somedomain.cloudfront.net/bucketsubfolder/media/somefile.pdf
        for item in bucket.list():
            if regex.match(item.name):
                new_list.append(item.name)
        return new_list

【问题讨论】:

  • 您不能在站点地图中使用外部网址(或者更确切地说,它们不会产生预期的效果)。我认为你最好的选择是在你的网站上创建一个路径,比如/hosted/pdf/xxxx.pdf,使用重写/位置模式重定向到cloudfront.com/pdf/xxxx.pdf或类似的路径。这样,您可以在站点地图中使用站点 URL,但仍将浏览器直接发送到云端提供的内容。
  • 好的,我认为这会有所帮助,解决了 1/2 的问题。您知道如何以编程方式在 django 站点地图中包含 PDF 吗?
  • 恐怕我很久没做过Django了,但本质上应该在Sitemap类中有一个items()来返回内容,所以你想手动添加一些东西在返回之前列出。我认为你可以通过扩展Sitemap 来做类似于他们在docs.djangoproject.com/en/1.9/ref/contrib/sitemaps 中显示的事情,就像他们对BlogSitemap 类所做的那样。 (检查标题#sitemap-for-static-views。)
  • 你说得对,这是可能的,但唯一的缺点是我必须手动添加它们。谢谢你的帮助
  • @kb 我已经用一种不同的方法成功地完成了这项任务,所以请在上面写下你的建议的答案,这样我就可以接受它并给你赏金。谢谢!

标签: django media sitemap


【解决方案1】:

您不得在站点地图中使用外部网址(或者更确切地说,它们不会具有被 Google 索引为您网站内容的一部分的预期效果)。

我认为您最好的选择是在您的网站上指定一个路径,例如 /hosted/pdf/xxxx.pdf,使用 mod_rewrite/location patterns/regex 将所有内容重写为 cloudfront.com/pdf/xxxx.pdf 或类似内容。

这样您可以在站点地图中使用本地站点 URL,但仍然可以将浏览器直接发送到云端服务内容,我认为这甚至可以很好地使用 302 HTTP 状态代码。

Sitemap 类中有一个items() 方法可以返回要包含在sitemap.xml 中的内容,您可以创建自己的类来扩展它并添加其他数据。

您可以手动添加在方法中硬编码的数据,但我认为首选的选项是创建一个模型,该模型代表每个远程托管文件,并包含在站点地图中输出它所需的信息。 (这还允许您添加属性,例如基于每个文件的可见性,并允许您通过管理员对其进行管理,假设您为其设置了 ModelAdmin。)

我认为您可以使用扩展SitemapBlogSitemap 类来执行类似于http://docs.djangoproject.com/en/1.9/ref/contrib/sitemaps 中显示的操作。请务必检查该页面上的标题“静态视图的站点地图”。

我的建议是您选择模型方法来表示文件,因此您将托管的 PDF(或其他 CDN 内容)作为称为 StaticHostedFile 或类似名称的模型,并在 items() 中遍历所有这些部分。它确实需要您索引所有当前 PDF 以为它们创建模型,并在添加新 PDF 时创建新模型(但这可以自动化)。

很高兴知道您可以在 sitemap.xml 中添加“包含”,这样您就可以将网站内容拆分为两个站点地图(内容 + pdf)并将两者都包含在 sitemap.xml 中,例如:

<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <sitemap>
        <loc>http://www.example.com/original_sitemap.xml</loc>
        <lastmod>2016-07-12T09:12Z</lastmod>
    </sitemap>
    <sitemap>
        <loc>http://www.example.com/pdf_sitemap.xml</loc>
        <lastmod>2016-07-15T08:55Z</lastmod>
    </sitemap>
</sitemapindex>

尽管如此,这仍然需要本地 URL 和重写,但是当您有多个单独的站点地图要组合时,它可能是一个绝妙的技巧。 (例如,如果在一个子目录下运行 Django 站点,在另一个子目录下运行 Wordpress 站点。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多