Реализовать в бэкенде функцию «лайк» типа «Facebook» - PullRequest
0 голосов
/ 05 июня 2018

Я работаю над сайтом, созданным в Django, и хочу внедрить кнопку типа Facebook (или любой тип социальных сетей) like.У меня есть таблица user и таблица post, и я хочу, чтобы пользователям нравились сообщения.Меня смущают некоторые конкретные вещи:

  • Как я могу связать информацию пользователя с лайками, чтобы один пользователь мог понравиться только один раз?

Мой текущий подход:

  • Я думаю о создании нового поля в таблице post, скажем post_likes, в которой есть список пользователей, которым в данный момент нравитсяпост.Затем, перед рендерингом шаблона 'post', я должен обойти всех пользователей (в поле post_likes), чтобы проверить, нравится ли request.user сообщение или нет (в views.py), и отправить эти данные в шаблон(чтобы изменить пользовательский интерфейс кнопки like на liked), но этот подход мне кажется очень наивным, тоже медленным.Какие могут быть лучшие подходы?

1 Ответ

0 голосов
/ 05 июня 2018

Мы можем сделать это, создав две модели: Post (которые в действительности будут содержать дополнительные данные, такие как message, author и т. Д.) И Like, который действуеткак отношение многие ко многим между Post и User:

class Post(models.Model):

    total_likes = models.IntegerField(default=0)
    likes = models.ManyToManyField(User, through='app.Like')

    def like(self, user):
        _, created = Like.objects.get_or_create(user=user, post=self)
        if created:
            self.total_likes += 1
            self.save()

    @classmethod
    def update_likes(cls):
        cls.objects.annotate(total=Count('likes')).update(total_likes=F('total'))

class Like(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    post = models.ForeignKey(Post, on_delete=models.CASCADE)

Таким образом, функция like(..) используется для , как пост (с параметром пользователь).Таким образом, мы можем назвать somepost.like(someuser).Он извлечет или создаст новый объект Like, который сопоставляется с конкретным post и конкретным user.Если экземпляр Like уже существует, ничего не происходит, в противном случае мы увеличиваем поле total_likes, в котором хранится общее количество лайков.

Возможно, вы не хотите обновлять этот счетчик каждый раз, когда пользователю нравитсяpost: в конце концов, это создает дополнительную нагрузку на сервер.В этом случае, часть if created: может быть опущена, и мы должны регулярно звонить Post.update_likes.Эта функция будет выполнять агрегирование за Post, которое подсчитывает количество лайков, и обновляет поле total_likes.

Независимо от того, постоянно ли вы обновляете total_likes, лучше время от времениобновить общее количество лайков на пост.Так как другие виды, модели и т. Д. Могут - учитывая, что разработчики не очень строго к этому относятся - удалять объекты Like.Кроме того, User s могут быть удалены и т. Д., И мы не очень контролируем это.Да, мы можем создавать сигналы, которые срабатывают после удаления (и создания) Like s и User s, но все же могут быть проблемы с подсчетом количества лайков, таких как условия гонки .Поэтому я бы посоветовал периодически обновлять количество лайков.

...