Как отследить, какие записи понравились пользователю? - PullRequest
0 голосов
/ 29 апреля 2020

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

У меня есть список -страница, отображающая каждое сообщение в базе данных как компонент Content Card. Этот компонент содержит значок, упомянутый выше. Чтобы решить, должен ли компонент отображаться с выделенным или заполненным сердцем, мне нужен способ установить, понравился ли пользователю соответствующий пост или нет.

Что я сейчас делаю

Каждый лайк - это собственный экземпляр модели Like, который имеет внешний ключ, указывающий на сообщение, которое связано с ним. У меня есть конечная точка API на content/likes/?post_id=${postID}, которая дает мне всех пользователей, которым понравился данный пост.

Для каждого поста на странице я вызываю эту конечную точку, а затем l oop поверх ответа на Посмотрите, есть ли зарегистрированный пользователь в этом списке пользователей, которым понравился контент. Если это так, я устанавливаю состояние true, и сердце для этого сообщения заполнено.

Мой подход работает нормально , но Я делаю отдельный запрос для каждого сообщения в стр. Допустим, у меня отображается 100 сообщений, и я предполагаю, что было бы нецелесообразно делать 100 запросов только для того, чтобы заполнить этот значок.

Я думал о том, как улучшить это, но я не уверен, как люди обычно справляются с этим. Любая помощь приветствуется!

1 Ответ

1 голос
/ 29 апреля 2020

Как насчет конечной точки группового лайка?

content/batch_likes/?post_ids=1,2,3,4,5...

и возвращаемое значение либо понравившихся идентификаторов

[1,3,5]

, либо карты предпочтений:

{"1": true, "2": false, "3": true, "4": false, "5": true}

Они оба могут быть реализованы очень эффективно : Список:

liked_ids = Like.objects.filter(user=self.request.user, post_id__in=post_ids).values_list('post_id', flat=True)

Dict (используя вышеприведенное):

like_map = dict.fromkeys(post_id, False)
like_map.update({liked_id: True for liked_id in liked_ids})

РЕДАКТИРОВАТЬ:

Вы также можете выставить это в сериализаторе DRF:

class PostSerializer(serializers.ModelSerializer):
    user_liked = serializers.SerializerMethodField()
    # ... other fields and meta ...

    def get_user_liked(self, obj) -> bool:
        # See if we'd cached this...
        if hasattr(obj, '_user_liked'):
             return obj._user_liked
        # Or if we didn't, do a query (boo-hoo, slow)
        return self.obj.like_set.filter(user=self.context['request'].user).exists()

Затем вы можете добавить предварительную выборку в свой набор представлений DRF, чтобы получить это _user_liked свойство «кэширования» для ваших объектов в одном запросе.

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

...