Garrett
Garrett

Reputation: 1792

different text depending on if user has liked a post

I have this if statement in my template to display different buttons depending on if a user had like a post. There are the same trigger link, url, and view, however the text either says "Like" or "Unlike" depending on if the user has previously liked that post or not. However it is not working, no errors, just not working.

likes is a ManyToManyField in the UserPost model.

Template:

{% for post in posts %}
    <div class="single-post">
        <div class="post-header">
            <a class="link inline-block" href="{% url 'feed:post_detail' post.id %}">
                <h2 class="post-title">{{ post.title }}</h2>
            </a>

            <div class="post-interaction">
                {% if request.user.username in post.likes %}
                    <a class="link right-margin" href="{% url 'feed:post_like' post.id %}">
                        Unlike: {{ post.likes.count }}
                    </a>
                {% else %}
                    <a class="link right-margin" href="{% url 'feed:post_like' post.id %}">
                        Like: {{ post.likes.count }}
                    </a>
                {% endif %}
                <a class="link right-margin" href="{% url 'feed:post_detail' post.id %}">
                    Comments: {{ post.comments.count }}
                </a>
            </div>
        </div>

        {% if post.image %}
            <img class="post-pic" src="{{ post.image.url }}">
        {% endif %}

        <p class="post-body more-top-margin">{{ post.post_body }}</p>

        <div class="divider"></div>

        <p class="message-hint post-meta">{{ post.author }}</p>
        <p class="message-hint post-meta">{{ post.post_date }}</p>
        {% if request.user.is_authenticated and request.user == post.author or request.user.userprofile.user_level == 'admin' or request.user.userprofile.user_level == 'moderator' %}
            <a class="link right-margin" href="{% url 'feed:edit_post' post.id %}">
                Edit Post
            </a>
            <a class="link right-margin" href="{% url 'feed:delete_post' post.id %}">
                Delete Post
            </a>
        {% endif %}
    </div>
{% endfor %}

Views.py:

class HomeView(LoginRequiredMixin,ListView):
    login_url = 'account_login'
    model = UserPost
    template_name = 'feed/userpost_list.html'
    context_object_name = 'posts'
    paginate_by = 25
    queryset = UserPost.objects.all()

Model:

class UserPost(models.Model):
    author = models.ForeignKey(User,related_name='userpost',null=True)
    post_date = models.DateTimeField(auto_now_add=True)
    title = models.CharField(max_length=150,blank=False)
    post_body = models.TextField(max_length=1000,blank=False)
    image = models.ImageField(upload_to='post_pics',blank=True)
    likes = models.ManyToManyField(User,blank=True,related_name='post_likes')

    class Meta:
        ordering = ['-post_date']

    def publish(self):
        self.save()

    def get_absolute_url(self):
        return reverse('index')

    def likes_as_flat_user_id_list(self):
        return self.likes.values_list('user_id', flat=True)

    def __str__(self):
        return self.title

Upvotes: 0

Views: 366

Answers (1)

spin
spin

Reputation: 61

You could add a function to the UserPost model that exports the likes as a flat list, like this:

def likes_as_flat_user_id_list(self):
  return self.likes.values_list('id', flat=True)

Not sure of the exact code required, as you have not posted your model.

You should then be able to do something like this in your template (again, might be slightly different depending on your models):

{% if request.user.id in post.likes_as_flat_user_id_list %}

EDIT:

It's probably more efficient to create a flat list of posts that the user liked and pass it in as a template argument, and check if the post id is contained in that list. The above code creates such a flat list for every post.

Upvotes: 2

Related Questions