Search code examples
pythondjangoformscomments

Comment not being added to the database


I am working on a movie website with Django and I'm trying to add user comments. Only the registered users should be allowed to comment. I have the following so far: models.py:

class Comment(models.Model):
    movie = models.ForeignKey(Movie, related_name = "comments", on_delete=models.CASCADE)
    user = models.ForeignKey(User, on_delete = models.CASCADE)
    content = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return '%s - %s' % (self.movie.title, self.name)

forms.py

class CommentForm(forms.ModelForm):
    content = forms.CharField(label ="", widget = forms.Textarea(
    attrs ={
        'class':'form-control',
        'placeholder':'Comment here!',
        'rows':5,
        'cols':50
    }))
    class Meta:
        model = Comment
        fields =['content']

views.py

class MovieDetailsView(generic.DetailView):
      model = Movie
      template_name = "details.html"
    
      def comment(request, id):
        movie= Movie.objects.get(id)
        if request.method == 'POST':
          cf = CommentForm(request.POST or None)
          if cf.is_valid():
            content = request.POST.get('content')
            comment = Comment.objects.create(movie = movie, user = request.user, content = content)
            comment.save()
            return redirect(movie.get_absolute_url())
          else:
            cf = CommentForm()
              
      context ={
        'comment_form':cf,
        }
      return render(request, 'details.html', context)

details.html

<form method="POST" action="#" class="form">
    {% csrf_token %}
    {{comment_form.as_p}}
    <button type="submit" class="btn btn-primary  btn-lg">Submit</button>
    <textarea id="text" name="text" class="form__textarea" placeholder="Add comment"></textarea>
    <button type="button" class="form__btn">Send</button>
</form>

The MovieDetailsView displays the details page of the movie and has a comment section. However, when I submit the comment, it simply displays a white page and this link: http://127.0.0.1:8000/details/1# . The comment is not saved on the database and I can't seem to find what the issue is. I am also following the example from this link. Thanks in advance!


Solution

  • You can combine FormMixin with DetailView - Using FormMixin with DetailView.

    from django.urls import reverse
    from django.views.generic.detail import DetailView
    from django.views.generic.edit import FormMixin
    from django.http import HttpResponseForbidden
    
    
    class MovieDetailsView(FormMixin, DetailView):
        model = Movie
        template_name = "details.html"
        form_class = CommentForm
    
        def get_success_url(self):
            return reverse('movie_detail', kwargs={'pk': self.object.pk})
            # or
            # return self.object.get_absolute_url()
    
        def post(self, request, *args, **kwargs):
            if not request.user.is_authenticated:
                return HttpResponseForbidden()
            self.object = self.get_object()
            form = self.get_form()
            if form.is_valid():
                return self.form_valid(form)
            else:
                return self.form_invalid(form)
    
        def form_valid(self, form):
            form.instance.user = self.request.user
            form.instance.movie = self.object
            form.save()
            return super().form_valid(form)

    In the post() method, we first check if the user is logged in:

    if not request.user.is_authenticated:
        return HttpResponseForbidden()
    

    In template:

    <form method="POST" class="form">
        {% csrf_token %}
        {{ form.as_p }}
        <button type="submit" class="btn btn-primary  btn-lg">Submit</button>
    </form>
    

    You can remove the action attribute, the form will be submitted to the same page.