Form post request running wrong view method on Django

Submitted 3 years, 8 months ago
Ticket #106
Views 322
Language/Framework Django
Priority High
Status Closed

I'm trying to clone the Instagram web page using Django(version-3.1). My Django project has an app called 'post'. One of its template I have a form that is posting a comment to a post. The Form post request should call path('add_comment/',views.add_comment,name='add_comment') , but It's calling path('<slug:slug>/',views.post_details,name='post_details') and running the post_details() method on view.py instead of add_comment() method. Because of that it's showing DoesNotExist at /post/add_comment Error. I added print() statement at the beginning on both add_comment() and post_details() methods to find out which is running when the request is made.
The project Github linkgithub.com/mirasel/Instagram_Clone

The post_details.html template

{% extends 'base.html' %}
{% load static %}
{% block title %} post {% endblock %}
{% block profilephoto %} {{ propic.url }} {% endblock %}
{% block body %}
    <div>
        <div>
            <img src="{{post.image.url}}" alt="post" height="250px" width="250px">
        </div>
        <div>
            <a href="{% url 'instagram:profile' post.uploader %}">
                <img src="{{uploader.profile_pic.url}}" alt="{{uploader}}" style="border-radius: 50%;" height="24px" width="24px">
                 {{ post.uploader }}
            </a><br>
            <p>{{ post.date_published.date }}</p>
        </div>
        <div>
            <p>{{ post.caption }}</p>
        </div>
        <div>
            <form action="{% url 'post:add_comment' %}" id="comment_form" method="POST">
                {% csrf_token %}
                <textarea name="comment" id="comment" cols="30" rows="1" placeholder="Write a comment..."></textarea>
                <input type="hidden" name="slug" id="slug" value="{{post.slug}}">
                <!-- <input type="submit" style="display: none;" name="submit"> -->
            </form>
    <script>
        $(function(){
            $("#comment").keypress(function (e) {
                if(e.which == 13 && !e.shiftKey) {        
                    $(this).closest("form").submit();
                    e.preventDefault();
                }
            });
        });
    </script>
{% endblock %}

The views.py -

from django.shortcuts import render,redirect
from instagram.views import get_nav_propic,get_profile_details
from .models import UserPost,PostComment,PostLike
from django.http import JsonResponse

def get_post_likes(post):
    likes = PostLike.objects.filter(post=post)
    total_likes = len(likes)
    likers = []
    for l in likes:
        likers.append(get_profile_details(l.liker))
    return {'likers':likers,'total_likes':total_likes}


def get_post_comments(post):
    comments = PostComment.objects.filter(post=post)
    total_comments = len(comments)
    commenter = []
    comment = []
    for c in comments:
        commenter.append(get_profile_details(c.commenter))
        comment.append(c.comment)
    postcomment = zip(commenter,comment)
    return {'post_comment':postcomment,'total_comments':total_comments}


def upload_post(request):
    if request.method == 'POST':
        image = request.FILES['post_img']
        caption = request.POST['caption']
        uploader = request.user
        UserPost.objects.create(uploader=uploader,image=image,caption=caption)
        return redirect('instagram:feed')
    else:
        context = {
            'propic' : get_nav_propic(request.user)
        }
        return render(request,'post/upload_post.html',context)

def post_details(request,slug):
    print('I am here in post details')
    post = UserPost.objects.get(slug=slug)
    context = {
        'propic'    : get_nav_propic(request.user),
        'post'      : post,
        'uploader'  : get_profile_details(post.uploader),
        'LIKES'     : get_post_likes(post),
        'COMMENTS'  : get_post_comments(post),
    }
    return render(request,'post/post_details.html',context)

def add_comment(request):
    print('I am here in add comment')
    if request.method == 'POST':
        post_slug = request.POST.get('slug')
        post = UserPost.objects.get(slug=post_slug)
        user = request.user
        comment = request.POST.get('comment')
        PostComment.objects.create(post=post,commenter=user,comment=comment)
        return redirect('post:post_details',slug=post_slug)

The urls.py -

from django.urls import path
from . import views

app_name='post'

urlpatterns = [
    path('upload_post/',views.upload_post,name='upload_post'),
    path('<slug:slug>/',views.post_details,name='post_details'),
    path('add_comment/',views.add_comment,name='add_comment'),

]

The Error Page - Error Page preview

Submitted on Aug 09, 20
add a comment

1 Answer

@Mominul  I think this due to URL slug & add_comment pretty much same pattern. May be try adding the url paatern like this,

from django.urls import path
from . import views

app_name='post'

urlpatterns = [
    path('upload_post/',views.upload_post,name='upload_post'),
    path('<slug:slug>/',views.post_details,name='post_details'),
    #modified one
    path('comment/add_comment/',views.add_comment,name='add_comment'),

]

Submitted 3 years, 8 months ago

Thanks for the solution!! It works now. :D

- mominul 3 years, 8 months ago

Excellent. Kindly close the ticket from your end.

- Vengat 3 years, 8 months ago

Another solution I got is just putting the add_comment URL before the slug URL . like that - urlpatterns = [ path('upload_post/',views.upload_post,name='upload_post'), path('add_comment/',views.add_comment,name='add_comment'), path('<slug:slug>/',views.post_details,name='post_details'), ]

- mominul 3 years, 8 months ago

Yes rearranging also will work but you should be very careful when you use this pattern.

- Vengat 3 years, 8 months ago


Latest Blogs