Submit button in template leading to HTTP ERROR 405

Submitted 3 years ago
Ticket #8
Views 230
Language Django
Priority Low
Status Closed

I am adding a comment section for my posts, the issue is after submitting it leads to HTTP ERROR 405 This is the first time to receive this error, I have reviewed the views several times but I think the error might be from the views.py in post detail 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()
        post = get_object_or_404(Post, slug=self.kwargs['slug'])
        comments = Comment.objects.filter(post=post).order_by('-id')
        total_likes = post.total_likes()
        liked = False
        if post.likes.filter(id=self.request.user.id).exists():
            liked = True

        if self.request.method == 'POST':
            comment_form = CommentForm(self.request.POST or None)
            if comment_form.is_valid():
                content = self.request.POST.get('content')
                comment = Comment.objects.create(
                    post=post, user=request.user, content=content)
                comment.save()
                return HttpResponseRedirect("post_detail.html")
        else:
            comment_form = CommentForm()

        context["total_likes"] = total_likes
        context["liked"] = liked
        context["comments"] = comments
        context["comment_form"] = comment_form
        return context

here is the template


            <div class="main-comment-section">
            {{comments.count}} Comment{{comments|pluralize}}
            {% for comment in comments %}
            <blockquote class="blockquote">
                <p class="mb-0"> {{ comment.content}}</p>
                <footer class="blockquote-footer">by<cite title="Source Title">{{comment.user| capfirst}}</cite></footer>
            </blockquote>
            {% endfor %}

here are the comments models.py

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.TextField(max_length=160)
    timestamp = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return '{}-{}'.format(self.post.title, str(self.user.username))
Submitted on May 25, 20
add a comment

2 Answers

Verified

where is the form submission? .. what is your initial analysis on this?

Submitted 3 years ago

I have been trying to follow the logic of a function to be implemented in my classed view

- ahmed.hisham87 3 years ago

if you still want to stick with this approach , lets add print statement here if self.request.method == 'POST': comment_form = CommentForm(self.request.POST or None) if comment_form.is_valid(): content = self.request.POST.get('content') comment = Comment.objects.create( post=post, user=request.user, content=content) comment.save() print('Its working') return HttpResponseRedirect("post_detail.html")

- Vengat 3 years ago

any update on this?

- Vengat 3 years ago

it did not print

- ahmed.hisham87 3 years ago

Method Not Allowed (POST):

- ahmed.hisham87 3 years ago

exactly as its DetailedView, its not allowing to POST, as i mentioned above, can you use different view for POST the comment

- Vengat 3 years ago

how do you suggest to do it?

- ahmed.hisham87 3 years ago

create another function based view & submit the comment over there and redirect to whatever the page you like to

- Vengat 3 years ago

or try this ```def post(self, request, args, *kwargs): form = CommentForm(request.POST, request.FILES) if form.is_valid(): # Write Your Logic here

    self.object = self.get_object()
    context = context = super(Detail, self).get_context_data(**kwargs)
    context['form'] = CommentForm
    return self.render_to_response(context=context)

else:
    self.object = self.get_object()
    context = super(Detail, self).get_context_data(**kwargs)
    context['form'] = form
    return self.render_to_response( context=context)```
- Vengat 3 years ago

if you still want to stick with DetailView itself then use above logic

- Vengat 3 years ago

i hope this one fix your issue

- Vengat 3 years ago

I am getting somewhere but I got Exception Value: post() got an unexpected keyword argument 'slug'

- ahmed.hisham87 3 years ago

I am getting somewhere but I got Exception Value: post() got an unexpected keyword argument 'slug'

- ahmed.hisham87 3 years ago

show me the code?

- Vengat 3 years ago

I think this is right ``` def get_context_data(self, args, *kwargs): context = super(PostDetailView, self).get_context_data() post = get_object_or_404(Post, slug=self.kwargs['slug']) comments = Comment.objects.filter(post=post).order_by('-id') total_likes = post.total_likes() liked = False if post.likes.filter(id=self.request.user.id).exists(): liked = True

    if self.request.method == 'POST':
        comment_form = CommentForm(self.request.POST or None)
        if comment_form.is_valid():
            content = self.request.POST.get('content')
            comment = Comment.objects.create(
                post=post, user=self.request.user, content=content)
            comment.save()
            return HttpResponseRedirect("post_detail.html")
    else:
        comment_form = CommentForm()

    context["total_likes"] = total_likes
    context["liked"] = liked
    context["comments"] = comments
    context["comment_form"] = comment_form
    return context

def post(self, request, args, *kwargs):
    form = CommentForm(request.POST, request.FILES)
    if form.is_valid():  # Write Your Logic here
        self.object = self.get_object()
        context = context = super(
            PostDetailView, self).get_context_data(**kwargs)
        context['form'] = CommentForm
        return self.render_to_response(context=context)
    else:
        self.object = self.get_object()
        context = super(PostDetailView, self).get_context_data(**kwargs)
        context['form'] = form
        return self.render_to_response(context=context)

```

- ahmed.hisham87 3 years ago

so you are able to render the detail view but not able to POST right?

- Vengat 3 years ago

no I am getting post() got an unexpected keyword argument 'slug' with a wrong url http://127.0.0.1:8000/score/score/hthththt76/

- ahmed.hisham87 3 years ago

I quickly reproduce the logic , see below its perfectly working to me. you can check at your end with slight change instead id, it should be slug, class DetailPostView(DetailView): model = Post template_name = 'tutorial/tutorial_detail.html' fields = ['title']

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        # favorite = Favorite.objects.filter(add_favorite=True)
        form = CommentForm(self.request.POST or None)
        id = self.kwargs['pk']
        obj_post = Post.objects.get(id=id)
        context['form'] = form
        return context

    def post(self, request, *args, **kwargs):
        form = CommentForm(request.POST, None)
        if form.is_valid():
        # Write Your Logic here
            print('Its Saved')
            self.object = self.get_object()
            context = super(DetailPostView, self).get_context_data(**kwargs)
            return self.render_to_response(context=context)
- Vengat 3 years ago

I have followed your logic and amended somethings : The views: ``` class PostCommentCreateView(CreateView): model = Comment fields = ['content']

def get(self, request, slug, *args, **kwargs):
    raise Http404

def post(self, request, slug, *args, **kwargs):
    self.post = Post.objects.get_or_404(slug=slug) <-----Error 'Manager' object has no attribute 'get_or_404'
    self.user = request.user

    super().post(request, *args, **kwargs)

def form_valid(self, form):
    form.instance.post = self.post
    form.instance.user = self.user
    return super(PostCommentCreateView, self).form_valid(form)

Here is the urls: path('post/<slug:slug>/comment', PostCommentCreateView.as_view(), name='post-comment'), here is the template: <form action={% url 'score:post-comment' post.slug %} method="post" class="comment-form" action=".">
{% csrf_token %} {{ comment_form.as_p }} {% if request.user.is_authenticated %} <input type="submit" value="Submit" class="btn btn-outline-success"> {% else %} <input type="submit" value="Submit" class="btn btn-outline-success" disabled> You must be Logged in to Comment {% endif %} </form> ```

- ahmed.hisham87 3 years ago

why you are sending slug to POST.. see if its POST request then you just need to save the data using the form just like below def post(self, request, args, *kwargs): form = TaskForm(request.POST, None) if form.is_valid(): new_form = form.save(commit=False) new_form.user = request.user new_form.save()

    return redirect('/todo/')
- Vengat 3 years ago

still not working I've tried everything

- ahmed.hisham87 3 years ago

then may be i will setup a meeting sometime tomorrow. I am pretty sure, you are missing something in your code.

- Vengat 3 years ago

that will be great

- ahmed.hisham87 3 years ago

Can we connect around 5.30 PM PST today?

- Vengat 3 years ago

sure

- ahmed.hisham87 3 years ago

Awesome ..will send you the invite

- Vengat 3 years ago

sorry i have to postponed the meeting.. how about 7 PM PST or we can connect tomorrow?

- Vengat 3 years ago

I am ok with 7 PM PST

- ahmed.hisham87 3 years ago

sent you the invite

- Vengat 3 years ago

Thank you for this solution really appreciate it ``` class PostCommentCreateView(LoginRequiredMixin, CreateView): model = Comment fields = ['content', ] success_url = reverse_lazy('score:post-detail')

def post(self, request, *args, **kwargs):
    form = CommentForm(request.POST)
    if form.is_valid():
        post = form.save()
        post.save()
    print(args, kwargs, request.POST)
    return redirect('score:post-detail', slug=kwargs['slug'])

```

- ahmed.hisham87 3 years ago

Welcome. As you can always support us Donate . If you want :)

- Vengat 3 years ago

here is the template

{% csrf_token %} {{ comment_form.as_p }} {% if request.user.is_authenticated %} {% else %} You must be Logged in to Comment {% endif %}
{{comments.count}} Comment{{comments|pluralize}} {% for comment in comments %}

{{ comment.content}}

by{{comment.user| capfirst}}
{% endfor %}

Submitted 3 years ago

right way to submit the comment form to different views not to same Detailed view. That is not recommended one

- Vengat 3 years ago


Wanna Post Ad?
Reach a large group of audience by posting an ad about your business here. For more details
Drop us a Message

Latest Blogs