Как реализовать API персональной ленты новостей?

Я реализовал несколько моделей, для формирования блога и постов в нем.

При подписке пользователя на другой блог, у него должны формироваться персональная лента новостей. Где отображаются все посты пользователей на которых он подписан и Bool - переменная, с возможностью отметить, что пост был уже прочитан.

Как можно реализовать данную модель? Или есть какие-то другие варианты?

Модель подписки на блог.

class Follow(models.Model):
    user = models.ForeignKey(
        CustomUser,
        on_delete=models.CASCADE
    )
    blog = models.ForeignKey(
        Blog,
        on_delete=models.CASCADE,
        related_name='follows'
    )

    class Meta:
        constraints = [
            models.UniqueConstraint(
                fields=['user', 'blog'],
                name='unique_favorite'
            )
        ]

Модель поста.

class Post(models.Model):
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE
    )
    blog = models.ForeignKey(
        Blog,
        on_delete=models.CASCADE,
        related_name='posts',
    )
    title = models.CharField(
        max_length=50
    )
    text = models.TextField(
        max_length=140
    )
    time_create = models.DateTimeField(
        auto_now_add=True
    )

Ответы (1 шт):

Автор решения: Алексей Симонов

Реализовал решение для данной задачи через Django сигналы.

Изменил модель Post

class Post(models.Model):
    blog = models.ForeignKey(
        Blog,
        on_delete=models.CASCADE,
        related_name='posts'
    )
    title = models.CharField(
        'название',
        max_length=50
    )
    text = models.TextField(
        'текст поста',
        max_length=140
    )
    create_time = models.DateTimeField(
        auto_now_add=True
    )

    def __str__(self) -> str:
        return f'{self.title}'

Написал модель для формирования персональной даты для пользователя.

class Personalfeed(models.Model):
    user = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name='personalfeeds'
    )
    post = models.ForeignKey(
        Post,
        on_delete=models.CASCADE,
        related_name='personalfeeds'
    )
    readed = models.BooleanField(
        default=False
    )

    def __str__(self) -> str:
        return f'post of {self.post.blog}'

Сигналы для заполнения Personalfeed. (Нужно оптимизировать запросы)

@receiver(post_save, sender=Follow)
def create_follow(sender, instance, *args, **kwargs):
    posts = instance.blog.posts.all()
    for post in posts:
        Personalfeed.objects.create(user=instance.user,
                                    post=post)


@receiver(post_delete, sender=Follow)
def delete_follow(sender, instance, *args, **kwargs):
    posts = instance.user.personalfeeds.all()
    for post in posts:
        post.delete()


@receiver(post_save, sender=Post)
def create_post(sender, instance, *args, **kwargs):
    author = instance.blog
    if Follow.objects.filter(blog=author).exists():
        user = Follow.objects.get(blog=author).user
        Personalfeed.objects.create(post=instance,
                                    user=user)
→ Ссылка