ILAR
ILAR

Reputation: 25

Django form fields are not displayed

I want to make a form for adding comments, but I only display a form without fields for input, it does not give any errors. how it looks on the web-site, there should be a form to post a comment.

I would also like to know how this code can be improved.

Any help is appreciated!

Here is my forms.py:

    class CommentForm(forms.ModelForm):
        class Meta:
            model = Comment
            fields = ['body']

views.py:

def comments(request, id):
    if request.method == 'POST':
        cf = CommentForm(request.POST or None)
        if cf.is_valid():
            body = request.POST.get('body')
            comment = Comment.objects.create(post=post, user=request.name, body=body)
            comment.save()
            return redirect(post.get_absolute_url())
        else:
            cf = CommentForm()

        context = {
            'cf': cf,
        }
        return render(request, 'main/article_detail.html', context)

urls.py:

from django.urls import path, include
from . import views
from .views import *

urlpatterns = [
    path('', PostListViews.as_view(), name='articles'),
    path('article/<int:pk>/', PostDetailViews.as_view(), name='articles-detail'),
    path('register/', register, name='register'),
    path('login/', login, name='login'),
]

My form in template:

             <form method="POST">
             {% csrf_token %}
             {{ cf.as_p }}
                 <button type="submit" class="btn btn-primary" style="width: 100px;position: relative;">Submit</button>
             </form>

my models.py:

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User


class Article(models.Model):
    title = models.CharField(max_length=30)
    content = models.TextField()
    pub_date = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

    def __str__(self):
        return self.title


class Comment(models.Model):
    post = models.ForeignKey(Article, related_name='comments', on_delete=models.CASCADE)
    name = models.ForeignKey(User, on_delete=models.CASCADE)
    body = models.TextField()
    date = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['date']

    def __str__(self):
        return f'Comment {self.body} by {self.name}'

Upvotes: 0

Views: 159

Answers (2)

Rahul Mishra
Rahul Mishra

Reputation: 1

In your views, your else block is not indented with request.method if block and also use return render method... Also use data=request.post in your parentheses bracket instead of "request.post or none". Try this....it should work then....

Upvotes: 0

SLDem
SLDem

Reputation: 2182

In your views.py

def comments(request, id):
    if request.method == 'POST':
        cf = CommentForm(request.POST or None)
        if cf.is_valid():
            comment = cf.save(commit=False)
            comment.user = request.user
            comment.post = post # you also will have to query your post first (i presume thats what the id is for in the function declaration)
            comment.save()
            return redirect(post.get_absolute_url())
    else: # fix this
        cf = CommentForm()

        context = {
            'cf': cf,
        }
    return render(request, 'main/article_detail.html', context) # fix this

Your indentation is implying that the template will render only with the POST method, since when you're accessing the view you are calling a GET method, your render function never gets called.

Also just use regular form.save() method to save your objects to database, its much easier to understand. And you do have to query your post before assigning a comment to it.

Upvotes: 1

Related Questions