Reputation: 89
I am trying to create a comment page for a blog-style site that will list all of the previous comments for a single related post.
I am having trouble figuring out how to structure the view to get what I'm looking for. I have been trying to use related names to get the data but am not sure if that is the right method.
Here are my models:
class Post(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
title = models.CharField(max_length=128)
content = models.TextField()
image = models.ImageField(upload_to='post_pics', blank=True)
date_posted = models.DateTimeField(default=timezone.now)
def get_absolute_url(self):
return reverse('home')
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
user = models.ForeignKey(User, on_delete=models.CASCADE)
comment = models.TextField()
date_created = models.DateTimeField(default=timezone.now)
def get_absolute_url(self):
return reverse('home')
And here is my view:
class CommentCreateView(LoginRequiredMixin, CreateView):
model = Comment
template_name = 'home/comment-form.html'
fields = ['comment',]
def get_context_data(self, **kwargs):
context = super(CommentCreateView, self).get_context_data(**kwargs)
context['post'] = Post.objects.get(pk=self.kwargs['pk'])
comments = Post.comments.all()
context['comments'] = comments
return context
def form_valid(self, form):
form.instance.user = self.request.user
form.instance.post = Post.objects.get(pk=self.kwargs['pk'])
return super().form_valid(form)
I have been trying a bunch of different things. The above is just my latest attempt. When I try to run this one I get a 'ReverseManyToOneDescriptor' object has no attribute 'all'
error.
I don't know if I need to run a get_queryset()
function or maybe call a queryset
at the beginning of the view?
Know this is probably a very basic issue but I appreciate the help!
Upvotes: 1
Views: 977
Reputation: 1655
To get the comments, you can use a filter()
Class CommentCreateView(LoginRequiredMixin, CreateView):
model = Comment
template_name = 'home/comment-form.html'
fields = ['comment',]
def get_context_data(self, **kwargs):
context = super(CommentCreateView, self).get_context_data(**kwargs)
post = Post.objects.get(pk=self.kwargs['pk'])
context['post'] = post
comments = Comment.objects.filter(post=post)
context['comments'] = comments
return context
Upvotes: 1
Reputation: 51978
You do not need to pass comments
to template, you can simply use:
{% for comment in post.comments.all %}
{{ comment.comment }}
{% endfor %}
It is possible because you already defined related_name='comments'
in Comment
model.
Upvotes: 1