Как добавить кнопку Like/Dislike

Как добавить кнопку Like/Dislike

S0mebody



В этом мини-руководстве мы добавим в наш блог функцию Like/Dislike.


В качестве примечания, мы реализуем эту функцию при использовании вьюшек на основе классов для нашего BlogPost DetailView.


Давайте начнем, во-первых, в нашем models.py нам нужно добавить в нашу модель BlogPost следующие поля:

# models.py
class BlogPost(models.Model):
    ...
    likes = models.ManyToManyField(User, related_name='blogpost_like')

    def number_of_likes(self):
        return self.likes.count()

likes - это отношение «многие ко многим» с нашей моделью пользователя, означающее, что пользователи (объекты) могут иметь несколько лайков, а сообщения в блоге могут иметь несколько лайков. Функция number_of_likes вернет количество лайков для текущего объекта сообщения в блоге.


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

>> python manage.py makemigrations
>> python manage.py migrate

Давайте теперь создадим нашу вьюшку для нашей кнопки Like. В файле view.py прямо перед (или после) классом BlogPost DetailView определите функцию BlogPostLike:

# views.py
from django.shortcuts import get_object_or_404
from django.http import HttpResponseRedirect
from django.urls import reverse

def BlogPostLike(request, pk):
    post = get_object_or_404(BlogPost, id=request.POST.get('blogpost_id'))
    if post.likes.filter(id=request.user.id).exists():
        post.likes.remove(request.user)
    else:
        post.likes.add(request.user)

    return HttpResponseRedirect(reverse('blogpost-detail', args=[str(pk)]))

blogpost_id будет нашим идентификатором кнопки в нашем blogpost_detail.html. Каждый раз, когда вошедший в систему пользователь нажимает кнопку Like, мы извлекаем его id, а затем проверяем, понравился ли этот пользователь уже или нет текущий пост в блоге. Затем мы перенаправим пользователя на ту же страницу блога (например, обновление этой страницы).


ПРИМЕЧАНИЕ. К сожалению, мы не можем избежать обновления страницы после каждого нажатия кнопки Like/Dislike. Чтобы пропустить обновление, необходимо реализовать всю функциональность кнопки Like/Dislike внутри HTML-кода с подробным описанием блога, используя Ajax.js. В этом мини-руководстве не рассматривается этот тип реализации.


Теперь это тот же файл view.py, в котором мы реализовали наш BlogPost DetailView, нам нужно добавить в наш get_context_data следующее:

# views.py
class BlogPostDetailView(DetailView):
    model = BlogPost
    # template_name = MainApp/BlogPost_detail.html
    # context_object_name = 'object'

    def get_context_data(self, **kwargs):
        data = super().get_context_data(**kwargs)

        likes_connected = get_object_or_404(BlogPost, id=self.kwargs['pk'])
        liked = False
        if likes_connected.likes.filter(id=self.request.user.id).exists():
            liked = True
        data['number_of_likes'] = likes_connected.number_of_likes()
        data['post_is_liked'] = liked
        return data

В нашей функции get_context_data мы получим текущий первичный ключ записи блога и проверим, понравился ли данный пост в блоге текущему авторизованному пользователю. Мы сохраним этот оператор в локальной переменной, чтобы отправить его в качестве контекста в наш блогpost_detail на основе HTML. Мы также получим количество лайков (вызывая ранее написанную функцию), чтобы отобразить количество лайков непосредственно в нашем HTML-шаблоне.


Давайте также добавим это новое представление на основе функций в наш urls.py:

# urls.py
from django.urls import path
from .views import (
    ...
    BlogPostLike,
    ...
)

urlpatterns = [
    ...
    path('blogpost-like/<int:pk>', views.BlogPostLike, name="blogpost_like"),
    ...
]

Наконец, в наш blogpost_detail.html напишем следующее:

<!-- LIKES -->
{% if user.is_authenticated %}
  <form action="{% url 'blogpost_like' object.id %}" method="POST">
 {% csrf_token %}

 {% if post_is_liked %}
 <button type="submit" name="blogpost_id" value="{{object.id}}" class="btn btn-info">Unlike</button>
 {% else %}
 <button type="submit" name="blogpost_id" value="{{object.id}}" class="btn btn-info">Like</button>
 {% endif %}
  </form>
{% else %}
  <a class="btn btn-outline-info" href="{% url 'login' %}?next={{request.path}}">Log in to like this article!</a><br>
{% endif %}
<strong class="text-secondary">{{ number_of_likes }} Like{{ number_of_likes|pluralize }}</strong>

Готово!


Report Page