Django-способ создания «Ленты новостей» / «Обновление статуса» / «Поток активности» - PullRequest
15 голосов
/ 25 января 2010

Я хотел бы создать повторно используемое приложение Django, которое обрабатывает обновления статуса пользователей. Очень похоже на «ленту новостей» на Facebook.

Примеры использования включают, например:

  • Профессор может создать Задание из-за определенной даты, и каждый студент может видеть в ленте новостей, что задание было создано, с кратким описанием, датой его выполнения и ссылкой , чтобы увидеть полное описание. .
  • Он также может загрузить новый PDF, который он считает интересным для своих учеников. В ленте новостей должна отображаться информация об этом, например, описание pdf, ссылка для скачивания и ссылка для предварительного просмотра .
  • Ссылка на видео YouTube может быть размещена, и в новостной ленте отображается небольшая миниатюра , и, щелкнув, , видео кодируется с использованием JavaScript , и пользователь может смотрите прямо сейчас.

Одна из проблем заключается в том, как обрабатывать различные виды обновлений и отображать правильный «HTML-фрагмент» для него. Другой, что более важно, заключается в том, как разработать Модели этого «пути Джанго».

Что касается первого, я мог бы придумать два способа сделать это:

  1. Использование наследования модели;
  2. Использование родовых отношений.

Я искал, прежде чем писать здесь, но ничего не нашел. Я проверил Pinax, чтобы увидеть, если они реализовали это, но они этого не делают. Итак, я здесь, чтобы найти больше предложений о том, как справиться с этим хорошим и не хакерским способом.

Заранее спасибо,

Ответы [ 4 ]

16 голосов
/ 07 октября 2014

Python - отличный язык для создания потоков деятельности и новостных лент. Томмасо и я написали пакет Stream Framework. https://github.com/tschellenbach/stream-framework В настоящее время это наиболее используемое решение Python для создания новостных лент. Мы также предлагаем размещенное решение на https://getstream.io.. Клиент Django, безусловно, легче всего начать с: https://github.com/GetStream/stream-django и python можно найти здесь (https://github.com/getstream/stream-python)

Шаблонная часть работает так

{% load stream_django %}

{% for activity in activities %}
    {% render_activity activity %}
{% endfor %}

Это отобразит шаблон, расположенный в файле activity / tweet.html, с действием в качестве контекста. Например

{{ activity.actor.username }} said "{{ activity.object.body }} {{ activity.created_at|timesince }} ago"

Полные документы здесь: https://github.com/GetStream/stream-django#templating

Stream Framework позволяет создавать новостные ленты любого типа, используя Redis или Cassandra. Он построен в масштабе и создает отдельные новостные ленты с помощью процесса разветвления.

Помимо Stream Framework (который я, очевидно, предпочитаю), существует множество других решений. Полный список доступен на пакетах django: https://www.djangopackages.com/grids/g/activities/

Обратите внимание, что в новостных лентах есть несколько проблем, связанных с масштабированием. В целом существует 3 общих подхода:

Стратегии денормализации

Прицепные Большинство пользователей начинают таким образом. Открывая страницу канала, вы просто запрашиваете каналы у всех пользователей, на которых вы подписаны. Если пользовательские каналы хранятся в памяти, это будет продолжаться довольно долго. В конце концов, довольно трудно продолжать использовать такую ​​стратегию, хотя вам часто приходится запрашивать большинство узлов, хранящих фиды вашего пользователя.

Нажмите Пуш-подход записывает вашу активность во всех ваших фолловерах. Конечно, это означает, что вы тратите кучу ресурсов, но конечным результатом является предварительно рассчитанный фид на пользователя. Этот подход (хотя изначально не очень эффективный) хорошо масштабируется.

Комбинация Некоторые оптимизированные системы используют комбинацию этих двух подходов. Также см. Статью Yahoo на эту тему.

Варианты хранения

С точки зрения хранения всех этих данных наиболее распространенными являются Redis, Cassandra и MongoDB. Давайте быстро сравним это:

Redis Redis чрезвычайно прост в настройке и обслуживании. Однако он хранит данные только в памяти. Это означает, что вам придется оптимизировать порядок сериализации данных и, возможно, использовать резервную базу данных для менее часто запрашиваемых данных. Другая проблема заключается в том, что добавлять компьютеры в кластер Redis нетривиально.

MongoDB Mongo DB используется в основном несколькими проектами ruby, а также доступен в качестве бэкэнда для pump.io от e14n. Лично я никогда не запускал его в производстве, поэтому не могу правильно оценить этот вариант. Тем не менее, существует множество постов, посвященных проблемам производительности, масштабируемости и удобства обслуживания mongo.

Cassandra Fashiolista, Instagram и Spotify все используют Cassandra. Наше решение также использует Cassandra в качестве бэкэнда. Это чрезвычайно экономически выгодно, и вы можете легко добавить больше узлов. Единственная проблема заключается в том, что его сложно настроить и поддерживать.

Статьи

Кроме того, взгляните на этот пост с высокой масштабируемостью, где мы объясняем некоторые из проектных решений: http://highscalability.com/blog/2013/10/28/design-decisions-for-scaling-your-high-traffic-feeds.html

Чтобы узнать больше о дизайне кормов, я настоятельно рекомендую прочитать некоторые статьи, на которых мы основывали Feedly:

7 голосов
/ 25 января 2010

Я могу думать двумя способами:

Во-первых, может быть, вы могли бы сделать фиды для своих моделей Assigments, PdfFiles и Youtube link и использовать библиотеку feedparser для встраивания их в ваши новостные представления это простой способ, потому что вы можете определить в шаблонах код для каждого вида нового действия.

Второе, о чем я могу подумать, это создать класс Activity:

class Activity(models.Model):
    date = models.DateTimeField(auto_now_add = True)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

И с помощью сигналов создайте новый экземпляр Activity каждый раз, когда у вас есть новое назначение, загрузка PDF или ссылка на YouTube, и для каждого класса создайте метод, подобный render_to_html, таким образом в своем для просмотра, вы можете сделать для over Activity и вызвать метод render_to_html

5 голосов
/ 25 января 2010

После еще одного поиска в Google и одного полезного ключевого слова (" Activity "), которое diegueus9 упомянуло и о котором я раньше не думал, я смог найти более подходящий материал.

Во-первых, два сообщения в блоге о том, как создать блог с использованием django с использованием фреймворка ContentType:

После этого в другом посте, который дает советы о том, как уменьшить проблему (1 + n) запросов (что изначально было одной из моих проблем, но я не упомянул, чтобы не загромождать вопрос).

И, наконец, повторно используемое приложение Django, которое обладает некоторыми необходимыми мне функциями и может быть полезно для дальнейшего использования:

3 голосов
/ 25 января 2010

Родовые отношения были бы способом пойти сюда. Обязательно разрешите модель самостоятельно, а не объединяйте ее с таблицей обновлений.

...