How to over ride the get context data method in view

170 views
Skip to first unread message

Ahmed Khairy

unread,
May 13, 2020, 4:45:55 AM5/13/20
to Django users

I am currently trying to create a like button for my posts in Django

I have reached to the part where I can add a like but I am facing difficulty writing the code related to the view which linking the PostListView if there is user who liked it or not. I am getting an error: page Error 404 although everything is correct


this the views: 


class PostListView(ListView):
    model = Post
    template_name = "score.html"
    ordering = ['-date_posted']
    context_object_name = 'posts'
    queryset = Post.objects.filter(admin_approved=True)
    paginate_by = 5

    def get_context_data(self**kwargs):
        post = get_object_or_404(Post, id=self.request.POST.get('post_id'))
        context = super(PostListView, self).get_context_data(**kwargs)
        context['posts'][0].likes.filter(id=self.request.user.id).exists()
        is_liked = False
        if post.likes.filter(id=self.request.user.id).exists():
            is_liked = True
        context = {'post': post,
                   'is_like': is_liked,
                   }
        return context



def like_post(request):
    post = get_object_or_404(Post, id=request.POST.get('post_id'))
    is_liked = False
    if post.likes.filter(id=request.user.id).exists():
        posts.likes.remove(request.user)
        is_liked = False

    else:
        post.likes.add(request.user)
        is_liked = True

    return HttpResponseRedirect(post.get_absolute_url())


This is the model 


class Post(models.Model):
    designer = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    date_posted = models.DateTimeField(default=timezone.now)
    likes = models.ManyToManyField(User, blank=True, related_name='likes')

    def __str__(self):
        return self.title
Here is the
path('like/', like_post, name='like_post'),
here is the template: 
{% extends "base.html"%} {% block content %} {% for post in posts %}

<div style="padding-top: 200 px;"><strong>{{post.title}}</strong></div>

<form action="{% url 'score:like_post'%}" method="POST" class="ui form">
  {% csrf_token %} {% if is_like %}
  <input type="hidden" name="post_id" value="{{post.id}}" />
  <button class="ui button positive" type="submit">Unlike</button>
  {% else %}
  <button class="ui button negative" type="submit">Like</button>
  {% endif %}
</form>
<strong>Likes </strong>

{% endfor %} {% endblock content %} 


Andréas Kühne

unread,
May 13, 2020, 10:08:31 AM5/13/20
to django...@googlegroups.com
Hi,

There are a couple of errors in your code:

1. You are using a ListView and then trying to get an individual post? That is really strange
2. In your get_context_data method - you first get the context data, update it and then you set it to a new dict, so everything is reset in the dict.
3. you are trying to get the absolut url for your post, but aren't showing any post detail view.

Regards,

Andréas


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/583492d8-5252-4f86-8e8f-7593b582d404%40googlegroups.com.

Ahmed Khairy

unread,
May 13, 2020, 1:23:36 PM5/13/20
to Django users
Hi Andréas Kühne,

Regarding the first error

I have a list of posts in the listView and want to add the like button to each post so how should I fix it? 

Thank you 
To unsubscribe from this group and stop receiving emails from it, send an email to django...@googlegroups.com.

Andréas Kühne

unread,
May 13, 2020, 4:31:15 PM5/13/20
to django...@googlegroups.com
Hi again,

Bare with me - this is just written in this email - so:

1. Your listview is paginated by 5, so it will only show 5 posts - that's good for this exercise and how I would solve it.
2. Rewrite your get_context_data method to iterate over the posts:
    def get_context_data(self, **kwargs):
        context_data = super(PostListView, self).get_context_data(**kwargs)
        for post in context_data['posts']:
            post.is_liked = post.likes.filter(user=user).exists()
        return context

So now your page should show. In the page template:
% extends "base.html"%} {% block content %} {% for post in posts %}

<div style="padding-top: 200 px;"><strong>{{post.title}}</strong></div>

<form action="{% url 'score:like_post'%}" method="POST" class="ui form">
<input type="hidden" name="post_id" value="{{post.id}}" />
{% csrf_token %} {% if is_like %}
   <button class="ui button positive" type="submit">Unlike</button>
  {% else %}
  <button class="ui button negative" type="submit">Like</button>
  {% endif %}
</form>
{% endfor %} {% endblock content %} 
Something like this should give you the functionality you want - however it's still a bit cumbersome.

Regards,

Andréas


To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/aee352a1-2938-42a6-98cb-5d602abba567%40googlegroups.com.

Ahmed Khairy

unread,
May 13, 2020, 5:21:35 PM5/13/20
to Django users
Hi There, 

I have rewritten the get_context_data method to be like this but I am getting name 'user' is not defined:


class PostListView(ListView):
    model = Post
    template_name = "score.html"
    ordering = ['-date_posted']
    context_object_name = 'posts'
    paginate_by = 5

    def get_context_data(self**kwargs):
        context_data = super(PostListView, self).get_context_data(**kwargs)
        for post in context_data['posts']:
            post.is_liked = post.likes.filter(user=user).exists() <----- name 'user' is not defined
        return context

I am also using this template just for testing till fix the issue 

Thank you Andreas with me

Yamen Gamal Eldin

unread,
May 13, 2020, 6:34:03 PM5/13/20
to django...@googlegroups.com
I haven't seen any definition for user within ur function, so 
Change this 
post.is_liked = post.likes.filter(user=user).exists()

To this

post.is_liked = post.likes.filter(user=request.user).exists()


To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/58be585f-357c-4454-acad-6799abe2e43d%40googlegroups.com.

Ahmed Khairy

unread,
May 13, 2020, 8:09:13 PM5/13/20
to Django users
still showing the same error

Andréas Kühne

unread,
May 14, 2020, 6:54:06 AM5/14/20
to django...@googlegroups.com
Hi,

We can't solve all of your problems for you :) But that being said - in the get_context_data you don't have a parameter for the request, however in all CBV you get the request as a variable on the CBV itself - so change:

post.is_liked = post.likes.filter(user=request.user).exists()

To:


post.is_liked = post.likes.filter(user=self.request.user).exists()

Regards,

Andréas


To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/d65b8dcb-b7e3-472d-8892-fb4c8e477109%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages