I’m trying to create a follow and unfollow button that checks if a user has followed another profile, and if the user hasn’t, an option to follow the profile would show.
I’ve tried two different options but still struggling with getting it right.
MODELS.PY
class Followers(models.Model):
follower = models.ForeignKey('User', on_delete=models.CASCADE, null=True, related_name="follows_user")
follows = models.ManyToManyField(User, related_name="followed_by", symmetrical=False, blank=True)
def __str__(self):
return str(self.follower)
PROFILE.HTML
<form method="POST">
{% csrf_token %}
<h2>{{ profile }}</h2>
<p>@{{ profile }}</p>
<input type="hidden" value="{{user.username}}" name="follower">
<input type="hidden" value="{{user_object.username}}" name="user">
<!-- new -->
{% if profile != request.user %}
{% if profile in profile.follows.all %}
<button type="submit" class="btn btn-primary rounded-pill my-1 mx-1 py-1 py-1" name="follow" value="unfollow">Unfollow</button>
{% else %}
<button type="submit" class="btn btn-primary rounded-pill my-1 mx-1 py-1 py-1" name="follow" value="follow">Follow</button>
{% endif %}
{% else %}
<a href="{% url 'logout' %}">Log Out</a>
{% endif %}
<strong>Followed by</strong> <br/>
{% for following in profile.followed_by.all %}
{{ following }}
{% endfor %}
<strong>Follows</strong> <br/>
{% for i in profile.follows_user.all %}
@ {{ i }} <br/>
{% endfor %}
</form>
VIEWS.PY
def profile(request, user_id):
profile = User.objects.get(pk = user_id)
# following = Followers.objects.get(pk = user_id)
if request.user.is_authenticated:
if request.method == "POST":
# get current user id
current_user_profile = request.user
# get form data
action = request.POST['follow']
# confirming follow status via action
if action == "unfollow":
current_user_profile.followed_by.remove(profile)
else:
current_user_profile.follows.add(profile)
current_user_profile.save()
context = {
"profile": profile,
}
return render(request, "network/profile.html", context)
else:
messages.INFO(request, ("You must be logged in"))
return HttpResponseRedirect(reverse("index"))
The struggle I’m having with the above option is that in the below code rather than the followed user (“followee”) showing, the currently logged in user or the follower would show e.g Test1 follows Test2, but instead of Test2 showing, it shows Test1.
When i click on the follow button, it shows
"AttributeError at /profile/2 -'User' object has no attribute 'follows' - C:\Users\hp\Desktop\CS50\network\network\views.py, line 144, in profile
current_user_profile.follows.add(profile)
Then I tried to edit my views
VIEWS2.PY
def profile(request, user_id):
profile = User.objects.get(pk = user_id)
# following = Followers.objects.get(pk = user_id)
if request.user.is_authenticated:
if request.method == "POST":
follower = request.POST['follower']
follows = request.user
if Followers.objects.filter(follower=follower, follows=follows).first():
delete_follower = Followers.objects.get(follower=follower, follows=follows)
delete_follower.delete()
following = False
context = {
"profile": profile,
"following": following,
"follows": follows,
}
return render(request, "network/profile.html", context)
else:
new_follower = Followers.objects.create(follower=follower, follows=follows)
new_follower.save()
following = True
context = {
"profile": profile,
"following": following,
"follows": follows,
}
return render(request, "network/profile.html", context)
else:
messages.INFO(request, ("You must be logged in"))
return HttpResponseRedirect(reverse("index"))
PROFILE2.HTML
<form method="POST">
{% csrf_token %}
<h2>{{ profile }}</h2>
<p>@{{ profile }}</p>
<input type="hidden" value="{{user.username}}" name="follower">
<input type="hidden" value="{{user_object.username}}" name="user">
<!-- new -->
{% if profile != request.user %}
{% if profile in profile.follows.all %}
<button type="submit" class="btn btn-primary rounded-pill my-1 mx-1 py-1 py-1" name="follow" value="unfollow">Unfollow</button>
{% else %}
<button type="submit" class="btn btn-primary rounded-pill my-1 mx-1 py-1 py-1" name="follow" value="follow">Follow</button>
{% endif %}
{% else %}
<a href="{% url 'logout' %}">Log Out</a>
{% endif %}
</form>
This second option immediately redirects me to the index page.