How do I can implement Follow/Unfollow system with CBV in Django?

Viewed 28

I did a lot of attempts to create a following system. Who can describe in details how to implement this? My code shows a lot of errors. In AddFollower() and Remove follower() I get a profile I'm on and a current profile (my) and add or remove in database. But these functions don't work. Help me to find a solution, please

urls.py

urlpatterns = [
    path('', PostListView.as_view(), name='blog-home'),
    path('user/<str:username>/', GetUserProfile.as_view(), name='user-profile'),
    path('post/<int:pk>/', PostDetailView.as_view(), name='post-detail'),
    path('post/new/', PostCreateView.as_view(), name='post-create'),
    path('post/<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
    path('post/<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete'),
    path('about/', views.about, name='blog-about'),
    path('post-like/<int:id>/', views.post_like, name='post-like'),
    path('read-later/<int:id>/', views.read_later, name='read-later'),
    path('read-later-list/<str:username>/', ReadLaterListView.as_view(), name='read-later-list'),
    path('add-follower/<str:username>/', AddFollower.as_view(), name='add_follower'),
    path('remove-follower/<str:username>/', RemoveFollower.as_view(), name='remove_follower')

views.py

class AddFollower(LoginRequiredMixin, View):

    def post(self, request, *args, **kwargs):
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        profile = Profile.objects.get(user=user)
        profile.subscribers.add(request.user)

        return redirect('user-profile', username=profile.user.username)


class RemoveFollower(LoginRequiredMixin, View):
    def post(self, request, *args, **kwargs):
        user = get_object_or_404(User, username=self.kwargs.get('username'))
        profile = Profile.objects.get(user=user)
        profile.subscribers.remove(request.user)

        return redirect('user-profile', username=profile.user.username)

user_posts.html

    {% if is_following %}
       <form action="{% url 'remove_follower' user.username %}" method="POST">
        {% csrf_token %}
        <div class="buttons mt-3">
            <button type="submit" class="btn btn-dark px-4 ms-3">Unfollow</button>
        </div>
       </form>
        {% else %}
           <form method="POST" action="{% url 'add_follower' user.username %}">
            {% csrf_token %}
            <div class="buttons mt-3">
                <button type="submit" class="btn btn-dark px-4 ms-3">Follow</button>
            </div>
           </form>
    {% endif %}
               
2 Answers

You do not give list of errors. Complicated for finding a solution of your problem.

But, i see some errors in your code. in the post function, you access to user by user = self.kwargs.get('user'), but in url, you have pass only an id param, so you can retrieve your user with this line instead of previous:

from django.shortcuts import get_object_or_404

class AddFollower(LoginRequiredMixin, View):
    def post(self, request, *args, **kwargs):
        user = get_object_or_404(User, pk=kwargs.get('id'))
        profile = Profile.objects.get(user=user)
        profile.subscribers.add(request.user)
        return redirect('user-posts', id=profile.id)


class RemoveFollower(LoginRequiredMixin, View):
    def post(self, request, *args, **kwargs):
        user = get_object_or_404(User, pk=kwargs.get('id'))
        profile = Profile.objects.get(user=user)
        profile.subscribers.remove(request.user)
        return redirect('user-posts', id=profile.id)

I don't know if it the last errors. Please give us more details and message of errors.

So, finally I solved it. The problem was that I passed the wrong username in view. I got the logged in user's profile instead of current user, so I fixed it by adding a context data:

 user = self.kwargs.get('username')
 profile_user = User.objects.get(user=user)

And adding it to the template:

<form method="POST" action="{% url 'add_follower' profile_user.username %}">
{% csrf_token %}
<div class="buttons mt-3">
    <button type="submit" class="btn btn-dark px-4 ms-3">Follow</button>
</div>
</form>
Related