Reputation: 25
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
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
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