Django Query: Как найти все сообщения людей, на которых вы подписаны - PullRequest
0 голосов
/ 16 декабря 2018

В настоящее время я создаю веб-сайт с помощью Django Framework.Я хочу, чтобы на главной странице моего сайта отображались все сообщения пользователей, на которых подписан пользователь.Вот классы для Profile, Story и Follow:

class Profile(AbstractBaseUser, PermissionsMixin):
   email = models.EmailField(unique=True)
   first_name = models.CharField(max_length=30, null=True)
   last_name = models.CharField(max_length=30, null=True)

class Follow(models.Model):
   following = models.ForeignKey('Profile', on_delete=models.CASCADE, related_name="following")
   follower = models.ForeignKey('Profile', on_delete=models.CASCADE, related_name="follower")
   follow_time = models.DateTimeField(auto_now=True)

class Story(models.Model):
   author = models.ForeignKey('accounts.Profile', on_delete=models.CASCADE, related_name="author")
   title = models.CharField(max_length=50)
   content = models.TextField(max_length=10000)

Как вы видите, Follow использует два внешних ключа для представления следующего и подписчика.Есть ли способ запросить все истории от людей, за которыми следит пользователь?

Я действительно не знаю, что фильтровать.Или это может быть работа для агрегации?Если бы кто-то мог мне помочь, это было бы здорово!

following_feed = Story.object.filter(???).order_by('-creation_date')

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

Обратите внимание, что я не проверял код, который я публикую, поэтому сообщите мне, если что-то не хватает.
Во-первых, вам нужно получить все Profiles, которым следуют ваши пользователи.Тогда вы должны получить Stories, что у них есть.

followed_people = Follow.objects.filter(follower=current_user).values('following')
stories = Story.objects.filter(author__in=followed_people) 
0 голосов
/ 16 декабря 2018

Можно использовать двойные подчеркивания (__) для просмотра сквозных отношений (например, ForeignKey s и т. Д.).

Так что здесь мы можем фильтровать как:

Story.objects.filter(
    <b>author__following__follower=my_profile</b>
)

Таким образом, используя author, мы получаем ссылку на Profile автора, затем с following мы смотрим на модель Follow и, наконец, с follower мы снова получаемссылка на Profile (s): профиль (и) последователя (ей).

my_profile, конечно, необходимо заменить объектом Profile (профиль человека, который* follower из author s из Story s, которые вы хотите получить).

Это сгенерирует запрос вроде:

SELECT s.*
FROM story AS s
JOIN follow AS f ON f.following_id = s.author_id
WHERE f.follower_id = 123

, где 123 isid из my_profile.

Если человек следует за другим человеком несколько раз (здесь это может произойти, поскольку вы не обязываете, чтобы кортежи follower, following были уникальными в модели Follow), тогда соответствующие Story s будут получены , кратные раз.

Поэтому, вероятно, лучше добавить ограничение unique_together в модель Follow:

class Follow(models.Model):
    following = models.ForeignKey(
        'Profile',
        on_delete=models.CASCADE,
        related_name="following"
    )
    follower = models.ForeignKey(
        'Profile',
        on_delete=models.CASCADE,
        related_name="follower"
    )
    follow_time = models.DateTimeField(auto_now=True)

    class Meta:
        <b>unique_together</b> = (<b>('following', 'follower')</b>, )

Может также стоить увидеть модель Follow в качестве through модели ManyToManyField [Django-doc] .

...