Структура синдикации 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)
Другие вопросы по тегам