1

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

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

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

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

有没有办法绕过这个?

4

3 回答 3

1

这有点粗糙,但如果您不想放弃 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)
于 2018-02-03T02:20:22.410 回答
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 以便您可以修补该功能。

设置.py

INSTALLED_APPS = [
    'django_overrides',
    ...
]
于 2018-02-03T02:45:39.130 回答
1

我确实最终挖掘了联合源代码,并没有找到简单的方法来覆盖它,并做了一些 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 开始的。希望在未来的补丁中,它们允许支持像磁铁这样的协议。

于 2018-02-03T14:52:37.813 回答