afi
afi

Reputation: 603

How to add comment form in ListView Django?

Into: I have a queryset of multiple posts in listviewpage. i want to add comment form with each of post in listviewpage instead of detailpageview. i also include html form inside forloop of posts list

Problem: The code below is getting error 'ValidationError' object has no attribute 'get'

I would be grateful for any help.

models.py

class Comment(models.Model):
  
    user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    post = models.ForeignKey(Post, on_delete=models.CASCADE, null=True, blank=True)
    comments = models.TextField(max_length=1000, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)

views.py

def ListViewPage(request):
    queryset = Post.objects.all()
    comment = CommentForm(data=request.POST)
    if request.method == 'POST':
        try:
            pk = request.POST.get('pk')
            post = Post.objects.get(id=pk)
        except Post.DoesNotExist:
            return ValidationError(f'No Post by id {pk}')


        if comment.is_valid():
            com = comment.save(commit=False)
            com.posts = post
            com.save()

    context = {
        'posts': queryset,
        'form': comment
    }
    return render(request, 'post_list.html', context)

post_list.html

{% for object in sales %}
<div class="hpanel hblue">
    <div class="row">
        <div class="col-sm-3">
            <div class="project-label">Saler</div>
            <small>{{ object.user }}</small>
        </div>
        <div class="col-sm-4">
            <div class="project-label">Timestamp</div>
            <small>{{ object.created_on|naturalday }}</small>
        </div>
        <div class="col-sm-4">
            <div class="project-label">Product</div>
            <small>{{ object.created_on|naturalday }}</small>
        </div>
    </div>
    <form action="." method="POST"> {% csrf_token %}

        <div class="form-group">
            <textarea name="comments" id="id_comments" cols="30" rows="2" required class="form-control"
                placeholder="comments..."></textarea>
        </div>
        <button type="submit" class="btn btn-sm btn-default">submit</button>
    </form>
</div>
{% endfor %}

Upvotes: 1

Views: 220

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476574

You can not return aq ValidationError in the view, you need to return a HTTP response, or raise a Http404 exception for example:

from django.http import Http404
from django.shortcuts import redirect

def ListViewPage(request):
    queryset = Post.objects.all()
    if request.method == 'POST':
        try:
            pk = request.POST.get('pk')
            post = Post.objects.get(id=pk)
        except Post.DoesNotExist:
            raise Http404(f'No Post by id {pk}')
        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            comment_form.instance.posts = post
            comment_form.save()
            return redirect('name-of-some-view')
    else:
        comment_form = CommentForm()
    context = {
        'posts': queryset,
        'form': comment_form
    }
    return render(request, 'post_list.html', context)

Note: In case of a successful POST request, you should make a redirect [Django-doc] to implement the Post/Redirect/Get pattern [wiki]. This avoids that you make the same POST request when the user refreshes the browser.

Upvotes: 1

Related Questions