【问题标题】:Django syndication framework: prevent appending SITE_ID to the linksDjango 联合框架:防止将 SITE_ID 附加到链接
【发布时间】:2018-02-01 07:11:13
【问题描述】:

根据此处的文档:https://djangobook.com/syndication-feed-framework/

如果链接没有返回域,联合框架将 根据您的 SITE_ID 插入当前站点的域 设置

但是,我正在尝试生成磁铁供稿:链接。框架无法识别这一点并尝试附加 SITE_ID,这样链接最终会像这样(在 localhost 上):

<link>http://localhost:8000magnet:?xt=...</link>

有没有办法绕过这个?

【问题讨论】:

    标签: django django-syndication


    【解决方案1】:

    这是一种使用猴子修补的方法,更清洁。

    我喜欢为这些类型的东西创建一个单独的文件夹“django_patches”:

    myproject/django_patches/__init__.py

    from django.contrib.syndication import views
    from django.contrib.syndication.views import add_domain
    
    
    def add_domain_if_we_should(domain, url, secure=False):
        if url.startswith('magnet:'):
            return url
        else:
            return add_domain(domain, url, secure=False)
    
    
    views.add_domain = add_domain_if_we_should
    

    接下来,将其添加到您的 INSTALLED_APPS 以便您可以修补该功能。

    settings.py

    INSTALLED_APPS = [
        'django_overrides',
        ...
    ]
    

    【讨论】:

      【解决方案2】:

      这有点粗糙,但如果你不想放弃 Django 框架,这里有一个潜在的解决方案:

      问题是add_domain 方法被深埋在联合框架内的一个巨大方法中,我看不到一个干净的方法来覆盖它。由于此方法用于提要 URL 和提要项目,add_domain 的猴子补丁需要考虑这一点。

      Django 源码: https://github.com/django/django/blob/master/django/contrib/syndication/views.py#L178

      步骤:

      1:继承您正在使用的 Feed 类并复制粘贴覆盖巨大的方法get_feed

      2:修改行:

      link = add_domain(
          current_site.domain,
          self._get_dynamic_attr('item_link', item),
          request.is_secure(),
      )
      

      类似于:

      link = self._get_dynamic_attr('item_link', item)
      

      【讨论】:

        【解决方案3】:

        我确实最终挖掘了联合源代码,并没有找到简单的方法来覆盖它,并做了一些 hacky Monkey 补丁。 (不幸的是,我在看到这里发布的答案之前就做到了,我认为所有这些都可以和这个一样)

        我是这样做的:

        def item_link(self, item):
            # adding http:// means the internal get_feed won't modify it
            return "http://"+item.magnet_link
        
        def get_feed(self, obj, request):
            # hacky way to bypass the domain handling
            feed = super().get_feed(obj, request)
            for item in feed.items:
                # strip that http:// we added above
                item['link'] = item['link'][7:]
            return feed
        

        对于未来的读者,这是从 Django 2.0.1 开始的。希望在未来的补丁中,它们可以支持磁铁等协议。

        【讨论】:

          猜你喜欢
          • 2011-10-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多