Django 联合框架:防止将 SITE_ID 附加到链接
Django syndication framework: prevent appending SITE_ID to the links
根据此处的文档:https://djangobook.com/syndication-feed-framework/
If link doesn’t return the domain, the syndication framework will
insert the domain of the current site, according to your SITE_ID
setting
但是,我正在尝试生成磁力提要:链接。该框架无法识别这一点并尝试附加 SITE_ID,这样链接最终会像这样(在本地主机上):
<link>http://localhost:8000magnet:?xt=...</link>
有没有办法绕过这个?
这有点难,但如果您不想放弃 Django 框架,这里有一个潜在的解决方案:
问题是方法 add_domain
深埋在联合框架内的一个巨大方法中,我没有看到一种干净的方法来覆盖它。由于此方法同时用于提要 URL 和提要项目,因此 add_domain
的猴子补丁需要考虑这一点。
Django 源代码:
https://github.com/django/django/blob/master/django/contrib/syndication/views.py#L178
步骤:
1:Subclass 您正在使用的 Feed class 并复制粘贴覆盖 huge 方法 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)
这里有一种使用猴子修补的方法,更干净。
我喜欢为这些东西创建一个单独的文件夹"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',
...
]
我最终确实深入挖掘了联合源代码,并没有找到覆盖它的简单方法,并进行了一些骇人听闻的猴子修补。 (不幸的是,我在看到此处发布的答案之前就这样做了,我认为所有这些答案都会像这个一样有效)
我是这样做的:
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 开始的。希望在未来的补丁中,他们可以支持像磁铁这样的协议。
根据此处的文档:https://djangobook.com/syndication-feed-framework/
If link doesn’t return the domain, the syndication framework will insert the domain of the current site, according to your SITE_ID setting
但是,我正在尝试生成磁力提要:链接。该框架无法识别这一点并尝试附加 SITE_ID,这样链接最终会像这样(在本地主机上):
<link>http://localhost:8000magnet:?xt=...</link>
有没有办法绕过这个?
这有点难,但如果您不想放弃 Django 框架,这里有一个潜在的解决方案:
问题是方法 add_domain
深埋在联合框架内的一个巨大方法中,我没有看到一种干净的方法来覆盖它。由于此方法同时用于提要 URL 和提要项目,因此 add_domain
的猴子补丁需要考虑这一点。
Django 源代码: https://github.com/django/django/blob/master/django/contrib/syndication/views.py#L178
步骤:
1:Subclass 您正在使用的 Feed class 并复制粘贴覆盖 huge 方法 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)
这里有一种使用猴子修补的方法,更干净。
我喜欢为这些东西创建一个单独的文件夹"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',
...
]
我最终确实深入挖掘了联合源代码,并没有找到覆盖它的简单方法,并进行了一些骇人听闻的猴子修补。 (不幸的是,我在看到此处发布的答案之前就这样做了,我认为所有这些答案都会像这个一样有效)
我是这样做的:
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 开始的。希望在未来的补丁中,他们可以支持像磁铁这样的协议。