0

I am trying to use Ajax to submit a like button without getting the page refreshing, I have been getting several errors previously but now I am getting this error:

django.urls.exceptions.NoReverseMatch: Reverse for 'like_post' with arguments '('',)' not found. 1 pattern(s) tried: ['score/like/(?P<pk>[0-9]+)$']

I am not sure what is the reason. Need help to identify the error.

Here is the view:

class PostDetailView(DetailView):
    model = Post
    template_name = "post_detail.html"

    def get_context_data(self, *args, **kwargs):
        context = super(PostDetailView, self).get_context_data()
        stuff = get_object_or_404(Post, id=self.kwargs['pk'])
        total_likes = stuff.total_likes()
        liked = False
        if stuff.likes.filter(id=self.request.user.id).exists():
            liked = True
        context["total_likes"] = total_likes
        context["liked"] = liked
        return context


def LikeView(request, pk):
    # post = get_object_or_404(Post, id=request.POST.get('post_id'))
    post = get_object_or_404(Post, id=request.POST.get('id'))
    like = False
    if post.likes.filter(id=request.user.id).exists():
        post.likes.remove(request.user)
        like = False
    else:
        post.likes.add(request.user)
        like = True
    context["total_likes"] = total_likes
    context["liked"] = liked

    if request.is_ajax:
        html = render_to_string('like_section.html', context, request=request)
        return JsonResponse({'form': html})

Here is the url.py updated:

urlpatterns = [

    path('user/<str:username>', UserPostListView.as_view(), name='user-posts'),
    path('', PostListView.as_view(), name='score'),
    path('who_we_Are/', who_we_are, name='who_we_are'),
    path('<int:pk>/', PostDetailView.as_view(), name='post-detail'),
    path('like/<int:pk>', LikeView, name='like_post'),
    path('new/', PostCreateView.as_view(), name='post-create'),
    path('<int:pk>/update/', PostUpdateView.as_view(), name='post-update'),
    path('<int:pk>/delete/', PostDeleteView.as_view(), name='post-delete')
]

Here is the template:

                        <form class="mt-0" action="{% url 'score:like_post' post.pk %}" method='POST'>

                            {% csrf_token %}
                            <strong> Likes: {{total_likes}} </strong> 
                            {% if user.is_authenticated %}
                            {% if liked %}
                                <button id='like' type='submit' name='post_id' class= "btn btn-danger btn-sm" 
value="{{post.id}}"> Unlike </button>                            
                            {% else %}
                                <button id='like' type='submit' name='post_id' class= "btn btn-primary btn-sm" 
value="{{post.id}}"> Like </button>                            
                            {% endif  %}
                            {% else %}
                            <p><small><a href="{% url 'login' %}"> Login</a> to Like </small></p>
                            {% endif %}                   
                        </form>

here is the ajax


    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>


    <script type="text/javascript">
        $(document).ready(function(event){
            $(document).on('click','#like', function(event){
                event.preventDefault();
                $var pk= $(this).attr('value');
                $.ajax({
                    type:'POST',
                    url:'{% url "score:like_post" post.pk %}',  <---- Error in this line
                    data:{'id': pk, 'csrfmiddlewaretoken':'{{csrf_token}}'},
                    dataType:'json', 
                    success:function(response){
                        $('#like-section').html(response['form'])
                        console.log($('#like-section').html(response['form']));                    
                    },
                    error:function(rs, e){
                        console.log(rs.responseText);                   
                    },
                });
            });
        });
    </script>
A_K
  • 731
  • 3
  • 15
  • 40
  • `Reverse for 'like_post' with arguments '('',)' not found` is telling you that post.pk is None or an empty string. – Ben May 19 '20 at 21:02
  • It doesn't look like you're sending the post into the view's context. – Ben May 19 '20 at 21:05

1 Answers1

1

You need to send the post object in as context.

class PostDetailView(DetailView):
    model = Post
    template_name = "post_detail.html"

    def get_context_data(self, *args, **kwargs):
        context = super(PostDetailView, self).get_context_data()

        post = get_object_or_404(Post, id=self.kwargs['pk'])
        content["post"] = post

        total_likes = post.total_likes()
        liked = False
        if post.likes.filter(id=self.request.user.id).exists():
            liked = True
        context["total_likes"] = total_likes
        context["liked"] = liked
        return context
Ben
  • 2,348
  • 1
  • 20
  • 23
  • nothing change it is still showing ` django.urls.exceptions.NoReverseMatch: Reverse for 'like_post' with arguments '('',)' not found. 1 pattern(s) tried: ` – A_K May 19 '20 at 21:18
  • Maybe I'm not fully understanding the flow... you could try adding `content["post"] = post` to the `LikeView` – Ben May 19 '20 at 21:26
  • @AhmedKhairy Where does the ajax code live? in the post_detail.html template? – Ben May 19 '20 at 21:28
  • the ajax code is in a an html file called scripts linked to the base.html is this your question? because the error is indicating this html and the line of url in particular – A_K May 19 '20 at 21:30