Home > Enterprise >  how to create comments form in CBV?
how to create comments form in CBV?

Time:01-04

I created a model comments and it was easy to display comments at the bot of post , but how am I suppose to make a form to add comment in same page as art_detail. I mean I have to use a CreateView but ArtDetailView() uses DetailView so i cant put both in one view, and when i put them i separated views only one of views send data to template model:

class Comment(models.Model):
    writer = models.ForeignKey(get_user_model(),on_delete=models.CASCADE)
    art = models.ForeignKey(Art,on_delete=models.CASCADE)
    text = models.TextField(max_length=500)
    date = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.writer.username

views:

class CommentView(CreateView):
    model = Comment
    template_name = 'art_detail.html'
    fields = ['text']

    def form_valid(self, form):
        form.instance.art = Art.objects.get(id=self.id)
        form.instance.writer = self.request.user
        return super().form_valid(form)

class ArtDetailView(DetailView):
    model = Art
    template_name = 'art_detail.html'

to handle this comments idk even if i need a url or not ? can you please help with this problem

CodePudding user response:

You can create a form and use it by mixing both views like this :

class ArtDetailView(FormView, DetailView):
    model = Art
    form_class = CommentForm

    def get_context_data(self, **kwargs):
        context = super(ArtDetailView, self).get_context_data(**kwargs)
        context['form'] = self.get_form()
        return context


    def post(self, request, *args, **kwargs):
        return FormView.post(self, request, *args, **kwargs)

CodePudding user response:

CBV and FBV can achieve the same results, however seeing them in FBV can help you understand your view more than CBV. Below is an example of how you would apply this in a a FBV:

views.py

def post(request, pk):
    form = CommentForm()
    post = Post.objects.get(id=pk)
    if request.method == "POST":
        form = CommentForm(request.POST)
        if form.is_valid():
            comment = form.cleaned_data['comment']
            comment = form.save(commit=False)
            comment.post = post
            comment.save()

            return redirect('post_page', id=post.pk)
        else:
            return render(request, 'post_page.html', {'post': post, 'form':form})
    return render(request, 'post_page.html', {'post': post, 'form':form})

models.py

class Post(models.Model):
    post_title = models.CharField(max_length=200, null=True, blank=True)
    post_description = models.CharField(max_length=200, null=True, blank=True)
    post_complete = models.TextField(max_length=2000, null=True, blank=True)


class Comment(models.Model):
    comment = models.CharField(null=True, blank=False, max_length=500, verbose_name="Comment")
    commentor = models.CharField(max_length=50)
    post_related = models.ForeignKey(Post, related_name="comments", on_delete=models.CASCADE, null=True)

forms.py

class CommentForm(forms.ModelForm):

    commentor = forms.CharField(max_length = 40, label = False, required = True,error_messages={'required': 'Name is required'},
    widget=forms.TextInput(attrs={
        'oninvalid': "this.setCustomValidity('Name is required')",
        'onchange': "this.setCustomValidity('')",
        'class': 'form-control', 'placeholder': 'Name:'}))

    comment = forms.CharField(max_length = 500, label = False, required = True,error_messages={'required': 'Comment is required'},
    widget=forms.Textarea(attrs={
        'oninvalid': "this.setCustomValidity('Comment is required')",
        'onchange': "this.setCustomValidity('')",
        'class': 'form-control', 'placeholder': 'Comment:'}))


    class Meta:
        model = Comment
        fields = ['name','comment']

post_page.html (page that includes both post and related comments)

{{post.title}}
{{post.description}}
{{post.complete}}




{% for comment in post.comments.all %}
{{comment.commentor}}
{{comment.comment}}
{% endfor %}

urls.py

path('post_page/<pk>/', views.post, name='post_page'),

When linking to the post, make sure to add post.pk in href

Hope this helps

  • Related