I have been trying to create a comment section for a blog site. Comments should only be made by the site's users. I am able to make comments and display them in the comment section from the admin panel, but when the users submit comments they don't display in the webpage.
Here are my models.py:
class Sight(models.Model):
CATEGORY_MAX_LEN = 25
NAME_MAX_LEN = 30
LOCATION_MAX_LEN = 100
IMAGE_UPLOAD_TO_DIR = 'destinations/'
name_of_sight = models.CharField(
verbose_name='Name of Sight',
max_length=NAME_MAX_LEN,
unique=True,
)
location = models.CharField(
verbose_name='Location',
max_length=LOCATION_MAX_LEN,
)
category = models.ForeignKey(
Category,
on_delete=models.CASCADE,
# choices=CATEGORIES
)
description = models.TextField(
verbose_name='Description',
)
post_date = models.DateTimeField(
auto_now_add=True,
)
pros = models.TextField(
verbose_name='Pros',
null=True,
blank=True,
)
cons = models.TextField(
verbose_name='Cons',
null=True,
blank=True,
)
image = models.ImageField(
upload_to=IMAGE_UPLOAD_TO_DIR,
verbose_name='Image',
)
user = models.ForeignKey(
UserModel,
on_delete=models.CASCADE,
)
def __str__(self):
return '%s - %s' % (self.name_of_sight, self.user)
class SightComment(models.Model):
MAX_BODY_LENGTH = 500
sight = models.ForeignKey(
Sight,
related_name='sight_comments',
on_delete=models.CASCADE,
blank=True,
null=False,
)
body = models.TextField()
publication_date_and_time = models.DateTimeField(
auto_now_add=True,
blank=True,
null=False,
)
user = models.ForeignKey(
UserModel,
on_delete=models.CASCADE,
)
def __str__(self):
return '%s - %s' % (self.sight.name_of_sight, self.user)
My form.py:
class SightCommentForm(forms.ModelForm):
class Meta:
model = SightComment
fields = ('body',)
widgets = {'body': forms.Textarea(attrs={'class': 'form-control', 'cols': 30, 'rows': 4})}
labels = {
"body": ""
}
My view.py - it's interesting how if I leave "new_comment.user = user" whenever the current tries to make a comment on a sight, the author of the sight itself changes to the current user:
@login_required(login_url='accounts/login')
def sight_details(request, pk):
sight = Sight.objects.get(pk=pk)
comments = sight.sight_comments.all()
user_like_sights = Sight.objects.filter(pk=pk, user_id=request.user.pk)
user = request.user
if request.method == 'POST':
form = SightCommentForm(request.POST, instance=sight)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.user = user
new_comment.sight = sight
new_comment.body = new_comment
new_comment.save()
return redirect('sight details', pk)
else:
print("Invalid Form")
print("errors : {}".format(form.errors))
else:
form = SightCommentForm()
context = {
'is_owner': sight.user_id == request.user.id,
'sight_author': sight.user,
'sight': sight,
'has_user_liked_sight': user_like_sights,
'likes_count': sight.sightlike_set.count(),
'form': form,
'comments': comments,
}
return render(request, 'sights/sight_details.html', context)
And my template - only the comment part:
{% for comment in comments %}
<img src="{{ comment.user.profile.profile_image.url }}" alt="Image"
class="img-fluid mr-3 mt-1" style="width: 45px;">
<a href="{% url 'profile details' comment.user.pk %}">{{ comment.user.profile.first_name }}</a>
<small><i>on {{ comment.publication_date_and_time }}</i></small>
{{ comment.body|linebreaks }}
{% empty %}
{% endfor %}
<h4>Make a new comment</h4>
<form id="myForm" method="POST" action="{% url 'sight details' sight.pk %}" enctype="multipart/form-data">
{{ form.as_p }}
{% csrf_token %}
<div class="form-group mb-0">
<input type="submit" value="Leave a comment"
class="btn btn-primary font-weight-semi-bold py-2 px-3">
</div>
</form>