Структура синдикации Django: запретить добавление SITE_ID к ссылкам
Согласно документации здесь: https://djangobook.com/syndication-feed-framework/
Если ссылка не возвращает домен, структура распространения вставит домен текущего сайта в соответствии с настройкой SITE_ID.
Тем не менее, я пытаюсь создать магнит: ссылки. Фреймворк не распознает это и пытается добавить SITE_ID, чтобы ссылки заканчивались так (на локальном хосте):
<link>http://localhost:8000magnet:?xt=...</link>
Есть ли способ обойти это?
3 ответа
В конце концов я перерыл исходный код синдикации и не нашел простого способа переопределить его, и сделал несколько хакерских патчей. (К сожалению, я сделал это до того, как увидел ответы, опубликованные здесь, которые, как я полагаю, будут работать так же хорошо, как и этот)
Вот как я это сделал:
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. Надеемся, что в будущем патче они позволят поддерживать такие протоколы, как магнит.
Вот способ сделать это с исправлениями обезьяны, намного чище.
Мне нравится создавать отдельную папку "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',
...
]
Это немного грубовато, но вот потенциальное решение, если вы не хотите отказываться от инфраструктуры Django:
Проблема в том, что метод add_domain
похоронен глубоко в огромном методе в рамках синдикации, и я не вижу чистого способа переопределить его. Поскольку этот метод используется как для URL-адреса канала, так и для элементов канала, патч обезьяны add_domain
нужно будет рассмотреть это.
Источник Django: https://github.com/django/django/blob/master/django/contrib/syndication/views.py
шаги:
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)