I want to make reply to comments feature in Django - django

I have a simple project and I added a comment feature there. Now I want to add comment reply feature. When I write and send the answer, it registers to sql but I cannot show it on the frontend.
models.py
class Comments(models.Model):
comment_author = models.ForeignKey(ArticleForm, on_delete=models.CASCADE, related_name='comments')
commenter_name = models.ForeignKey(User, on_delete=models.CASCADE)
comment_content = models.TextField()
commented_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "'{}' commented by '{}'".format(self.comment_content, self.commenter_name)
class Meta:
ordering = ['-commented_date']
class ReplyComment(models.Model):
reply_comment = models.ForeignKey(Comments, on_delete=models.CASCADE, related_name='replies')
replier_name = models.ForeignKey(User, on_delete=models.CASCADE)
reply_content = models.TextField()
replied_date = models.DateTimeField(auto_now_add=True)
def __str__(self):
return "'{}' replied with '{}' to '{}'".format(self.replier_name,self.reply_content, self.reply_comment)
views.py
def detail(request,id):
article = get_object_or_404(ArticleForm,id=id)
comments = article.comments.all()
return render(request, 'detail.html', {'article': article, 'comments': comments})
def replyComment(request,id):
comments = Comments.objects.get(id=id)
if request.method == 'POST':
replier_name = request.user
reply_content = request.POST.get('reply_content')
newReply = ReplyComment(replier_name=replier_name, reply_content=reply_content)
newReply.reply_comment = comments
newReply.save()
messages.success(request, 'Comment replied!')
return redirect('index')
detail.html
<div class="container">
<a type="text" data-toggle="collapse" data-target="#reply{{comment.id}}" style="float: right;" href="">Reply</a><br>
{% if replies %}
{% for reply in replies %}
<div>
<div class="fw-bold"><small><b>Name</b></small></div>
<div style="font-size: 10px;">date</div>
<small>Reply comment</small><br>
</div>
{% endfor %}
{% endif %}
<div id="reply{{comment.id}}" class="collapse in">
<form method="post" action="/article/reply/{{comment.id}}">
{% csrf_token %}
<input name="replier_name" class="form-control form-control-sm" type="hidden">
<input name="reply_content" class="form-control form-control-lg" type="text" placeholder="Reply comment">
<button type="submit" class="btn btn-primary" style="float: right; margin-top: 5px;">Reply</button>
</form>
</div>
What I'm trying to do is pull the responses from the sql and show them below the comment
I will be glad if you can tell me a solution suitable for my codes. Thanks

Perhaps this will work:
{% for comment in comments %}
<div>{{ comment }}</div>
{% for reply in comment.replycomment_set.all %}
<div>
<div class="fw-bold"><small><b>Name {{ reply.replier_name }}</b></small></div>
<div style="font-size: 10px;">date {{ reply.replied_date }}</div>
<small>Reply comment {{ reply.content }}</small><br>
</div>
{% endfor %}
{% endfor %}

Related

Edit item within views in Django

There is some problem, I'm trying to update the product on the client by making changes and clicking on the update button - my page is refreshing w/o updating info, so the product has the same data as before. But in the logs, the status code of the GET request is 200 and shows the updated object in the database. When I try to update through the admin Django dashboard, everything works successfully, the problem is only on the client side of the web application. What issues can there be?
Thank you in advance!
models.py
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
CATEGORY = (
('Stationary', 'Stationary'),
('Electronics', 'Electronics'),
('Food', 'Food'),
)
class Product(models.Model):
name = models.CharField(max_length=100, null=True)
quantity = models.PositiveIntegerField(null=True)
category = models.CharField(max_length=50, choices=CATEGORY, null=True)
def __str__(self):
return f'{self.name}'
class Order(models.Model):
name = models.ForeignKey(Product, on_delete=models.CASCADE, null=True)
customer = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
order_quantity = models.PositiveIntegerField(null=True)
def __str__(self):
return f'{self.customer}-{self.name}'
views.py
#login_required(login_url='user-login')
#allowed_users(allowed_roles=['Admin'])
def product_edit(request, pk):
item = Product.objects.get(id=pk)
if request.method == 'POST':
form = ProductForm(request.POST, instance=item)
if form.is_valid():
form.save()
return redirect('dashboard-products')
else:
form = ProductForm(instance=item)
context = {
'form': form,
}
return render(request, 'dashboard/products_edit.html', context)
forms.py
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = '__all__'
html template:
{% extends 'partials/base.html' %}
{% block title %}Products Edit Page{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row my-4">
<div class="col-md-6 offset-md-3 p-3 bg-white">
<h3>Edit Item</h3>
<hr>
<form>
{% csrf_token %}
{{ form|crispy }}
<input class="btn btn-info" type="submit" value="Confirm">
</form>
</div>
</div>
{% endblock %}
You have forgotten to pass POST method you are using GET.
{% extends 'partials/base.html' %}
{% block title %}Products Edit Page{% endblock %}
{% load crispy_forms_tags %}
{% block content %}
<div class="row my-4">
<div class="col-md-6 offset-md-3 p-3 bg-white">
<h3>Edit Item</h3>
<hr>
<form method="post">
{% csrf_token %}
{{ form|crispy }}
<input class="btn btn-info" type="submit" value="Confirm">
</form>
</div>
</div>
{% endblock %}

How to add a form in an html page in django

I want to add comments form a specific html which has it's own views and models and I do not want to create a new html file like comment.html which will only display the form and its views. I want users to be able to comment right underneath a post, so that users don't have to click a button such as "add comment" which will take them to a new page with the "comment.form" and then they can comment. Basically want a page with all transfer news and their respective comments as well as a comment-form under the old comment. But I'm stuck. I can add comments manually from the admin page and it's working fine, but it seems that I have to create another url and html file to display the comment form and for users to be able to add comments(btw I'm trying to build a sports related website). Thanks in advance!
My models.py:
class Transfernews(models.Model):
player_name = models.CharField(max_length=255)
player_image = models.CharField(max_length=2083)
player_description = models.CharField(max_length=3000)
date_posted = models.DateTimeField(default=timezone.now)
class Comment(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
transfernews = models.ForeignKey(Transfernews, related_name="comments", on_delete=models.CASCADE)
body = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s - %s' % (self.transfernews.player_name, self.user.username)
My forms.py :
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('body', 'transfernews')
My views.py :
def addcomment(request):
model = Comment
form_class = CommentForm
template_name = 'transfernews.html'
def transfer_targets(request):
transfernews = Transfernews.objects.all()
form = CommentForm(request.POST or None)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.user = request.user
new_comment.save()
return redirect('transfernews/')
return render(request, 'transfernews.html', {'transfernews': transfernews})
My urls.py:
path('transfernews/', views.transfer_targets, name='transfernews'),
My transfernews.html:
<h2>Comments...</h2>
{% if not transfernew.comments.all %}
No comments Yet...
{% else %}
{% for comment in transfernew.comments.all %}
<strong>
{{ comment.user.username }} - {{ comment.date_added }}
</strong>
<br/>
{{ comment.body }}
<br/><br/>
{% endfor %}
{% endif %}
<hr>
<div>Comment and let us know your thoughts</div>
<form method="POST">
{% csrf_token %}
<input type="hidden" value="{{ transfernew.id}}">
<div class="bg-alert p-2">
<div class="d-flex flex-row align-items-start"><textarea class="form-control ml-1 shadow-none textarea"></textarea></div>
<div class="mt-2 text-right"><button class="btn btn-primary btn-sm shadow-none" type="submit">
Post comment</button><button class="btn btn-outline-primary btn-sm ml-1 shadow-none" type="button">Cancel</button></div>
</div>
</div>
</form>
Here's how you can do it :
First, add a field in your CommentForm :
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('body', 'transfernews')
Then in your template, you can set an hidden input in the form to link the comment to the transfernews :
{% if form.errors %}
<p>There are errors in your form :</p>
<ul>{{ form.errors }}</ul>
{% endif %}
<form method="POST">
{% csrf_token %}
{# Add this next line #}
<input type="hidden" value="{{ transfernew.id}}">
<div class="bg-alert p-2">
<div class="d-flex flex-row align-items-start">
<textarea class="form-control ml-1 shadow-none textarea" name="body"></textarea>
</div>
<div class="mt-2 text-right">
<button class="btn btn-primary btn-sm shadow-none" type="submit">Post comment</button>
<button class="btn btn-outline-primary btn-sm ml-1 shadow-none" type="button">Cancel</button>
</div>
</div>
</form>
Then in your view :
def transfer_targets(request):
transfernews = Transfernews.objects.all()
form = CommentForm(request.POST or None)
if form.is_valid():
new_comment = form.save(commit=False)
new_comment.user = request.user
new_comment.save()
return redirect('transfernews')
return render(request, 'transfernews.html', {
'transfernews': transfernews,
'form': form
})

Can I add a form in django in HTML

I want to add comments form a specific html which has it's separate views and models and I don't want to create a new form.html just to display the form and its views. But I'm stuck. I can add comments manually from the admin page and it's working fine, but it seems that I have to create another url and html file to display the comment form and for users to be able to add comments(btw I'm trying to build a sports related website). Thanks in advance!
My models.py:
class Transfernews(models.Model):
player_name = models.CharField(max_length=255)
player_image = models.CharField(max_length=2083)
player_description = models.CharField(max_length=3000)
date_posted = models.DateTimeField(default=timezone.now)
class Comment(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
transfernews = models.ForeignKey(Transfernews, related_name="comments", on_delete=models.CASCADE)
body = models.TextField()
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return '%s - %s' % (self.transfernews.player_name, self.user.username)
My forms.py :
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('body',)
My views.py :
def addcomment(request):
model = Comment
form_class = CommentForm
template_name = 'transfernews.html'
My urls.py:
path('comment/', views.addcomment, name='comment'),
My transfernews.html:
<h2>Comments...</h2>
{% if not transfernew.comments.all %}
No comments Yet...
{% else %}
{% for comment in transfernew.comments.all %}
<strong>
{{ comment.user.username }} - {{ comment.date_added }}
</strong>
<br/>
{{ comment.body }}
<br/><br/>
{% endfor %}
{% endif %}
<hr>
<div>Comment and let us know your thoughts</div>
<form method="POST">
{% csrf_token %}
<div class="bg-alert p-2">
<div class="d-flex flex-row align-items-start"><textarea class="form-control ml-1 shadow-none textarea"></textarea></div>
<div class="mt-2 text-right"><button class="btn btn-primary btn-sm shadow-none" type="submit">
Post comment</button><button class="btn btn-outline-primary btn-sm ml-1 shadow-none" type="button">Cancel</button></div>
</div>
</div>
</form>
You don't have to.
In your HTML, take out the anchor tag, you only need the submit button.
<form method="POST">
{% csrf_token %}
<div class="bg-alert p-2">
<div class="d-flex flex-row align-items-start">{{ form.body }}</div>
<div class="mt-2 text-right"><button class="btn btn-primary btn-sm shadow-none" type="submit">
Post comment</button><button class="btn btn-outline-primary btn-sm ml-1 shadow-none" type="button">Cancel</button></div>
</div>
In your views.py, do this.
def view_that_loads_the_page(request, news_id):
news = Transfernews.objects.get(id=news_id)
form_class = CommentForm(request.POST or None)
if form_class.is_valid():
# save both news and logged in user
form.instance.transfernews = news
form.instance.user = request.user
# save form.
form_class.save()
# returns to the same page
return HttpResponseRedirect(request.path_info)
return render(request, "your_html.html", {"form" : form_class})

Can't add normal Comment section in my Django web-application

I have trouble with adding comments to my django web-application. I want to add comments to allow users comment posts, like in normal web blog. I've tried a few ways, but nothing worked correctly for me.
After a few weeks searching and trying different ways to solve this question, I've stacked on this question. I have some progress, but it's now what I want completely.
Now I can only add "comments" from admin panel
and it look like this (from admin panel)
and like this (from user interface)
And I have this issue with padding comments( I don't really understand why it's occurs ¯_(ツ)_/¯ )
Anyway, here is my code, hope someone know how to solve this problem:
models.py
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(User, on_delete=models.CASCADE)
text = models.TextField()
created_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.text
...
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
categories = models.ManyToManyField('Category', related_name='posts')
image = models.ImageField(upload_to='images/', default="images/None/no-img.jpg")
slug= models.SlugField(max_length=500, unique=True, null=True, blank=True)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'slug': self.slug})
post_detail.html
<article class="media content-section">
{% for comment in post.comments.all %}
<ul>
{{ comment.text }}
{% for reply in comment.replies.all %}
<li>
{{ reply.text }}
</li>
{% endfor %}
<ul>
{% endfor %}
</article>
I also read this article about creation blog for beginners, and they have working comment section as I want, but I tried to implement their code to my web-app, and nothing worked for me.
They have comment section like this (I need completely the same one):
But when I tried to follow their tutorial, I have only like this:
And here is the code for this unsuccessful solution( but I feel like it is working one, maybe I did something wrong)
post_detail.html
{% extends 'blog/base.html' %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ object.author.profile.image.url }}" alt="">
<div class="article-metadata">
<a class="mr-2 author_title" href="{% url 'user-posts' object.author.username %}">#{{ object.author }}</a>
<small class="text-muted">{{ object.date_posted|date:"N d, Y" }}</small>
<div>
<!-- category section -->
<small class="text-muted">
Categories:
{% for category in post.categories.all %}
<a href="{% url 'blog_category' category.name %}">
{{ category.name }}
</a>
{% endfor %}
</small>
</div>
{% if object.author == user %}
<div>
<a class='btn btn-secondary btn-sm mt-1 mb-1' href="{% url 'post-update' object.slug %}">Update</a>
<a class='btn btn-danger btn-sm mt-1 mb-1' href="{% url 'post-delete' object.slug %}">Delete</a>
</div>
{% endif %}
</div>
</article>
<article class="media content-section">
<div class="media-body">
<img class="img-fluid center" id="rcorners3" src="{{ object.image.url }}" alt="none">
<h2 class="article-title text-center">{{ object.title }}</h2>
<p class="article-content">{{ object.content }}</p>
</div>
</article>
<article class="media content-section">
<form action="/blog/{{ post.pk }}/" method="post">
{% csrf_token %}
<div class="form-group">
{{ form.author }}
</div>
<div class="form-group">
{{ form.body }}
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<h3>Comments:</h3>
{% for comment in comments %}
<p>
On {{comment.created_on.date }}
<b>{{ comment.author }}</b> wrote:
</p>
<p>{{ comment.body }}</p>
<hr>
{% endfor %}
</article>
{% endblock content %}
views.py
...
def comment(request):
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = Comment(
author=form.cleaned_data["author"],
body=form.cleaned_data["body"],
post=post
)
comment.save()
comments = Comment.objects.filter(post=post)
context = {
"post": post,
"comments": comments,
"form": form,
}
models.py
...
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')
author = models.ForeignKey(User, on_delete=models.CASCADE)
text = models.TextField()
created_date = models.DateField(auto_now_add=True)
def __str__(self):
return self.text
forms.py
from django import forms
class CommentForm(forms.Form):
author = forms.CharField(
max_length=60,
widget=forms.TextInput(attrs={
"class": "form-control",
"placeholder": "Your Name"
})
)
body = forms.CharField(widget=forms.Textarea(
attrs={
"class": "form-control",
"placeholder": "Leave a comment!"
})
)
You are creating unnecessary lists. Try this one
<article class="media content-section">
<ul>
{% for comment in post.comments.all %}
<li>{{ comment.text }}</li>
{% if comment.replies.all %}
<ul>
{% for reply in comment.replies.all %}
<li>{{ reply.text }}</li>
{% endfor %}
</ul>
{% endif %}
{% endfor %}
<ul>
</article>

edit django form with instance always loads with empty form fields

models.py
class summary_model(models.Model):
username = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.PROTECT)
summary=models.TextField(unique=False, blank=False, null=False)
numberofprojects=models.CharField(max_length=264, unique=False, blank=False, null=False)
numberofinternships=models.CharField(max_length=264, unique=False, blank=False, null=False)
numberofjobs=models.CharField(max_length=264, unique=False, blank=False, null=False)
def __str__(self):
return str(self.username)
forms.py
class summary_form(forms.ModelForm):
#fields from model
class Meta:
model = summary_model
fields = ('summary','numberofprojects','numberofinternships','numberofjobs')
views.py
def summaryview(request):
username=request.user
if request.method == 'GET':
summaryform=summary_form(request.GET or None,instance=summary_model.objects.get(username=username))
print(summaryform)
elif request.method == 'POST':
form4=summary_form(request.POST or None,instance=summary_model.objects.get(username=username))
if form4.is_valid():
summary_obj = form4.save(commit=False)
summary_obj.username = request.user
summary_obj.save()
return redirect('#anotherview')
else:
summaryform=summary_form(instance =summary_model.objects.get(username =username))
return render(request,'app/summary.html',{'summaryform':summary_form,})
template/summary.html
{% block content %}
<form action="" method="post" novalidate>
{% csrf_token %}
{{ summaryform.non_field_errors }}
<div class="row form-row bg-white has-shadow">
<div class="col-12">
<span class="labelspan">{{ summaryform.summary.label }}</span>
{{ summaryform.summary.errors }}
<span class="inputfieldspan">{{ summaryform.summary}}</span>
</div>
<div class="col-6">
<span class="labelspan">{{ summaryform.numberofprojects.label }}</span>
{{ summaryform.numberofprojects.errors }}
<span class="inputfieldspan">{{ summaryform.numberofprojects}}</span>
</div>
<div class="col-6">
<span class="labelspan">{{ summaryform.numberofinternships.label }}</span>
{{ summaryform.numberofinternships.errors }}
<span class="inputfieldspan">{{ summaryform.numberofinternships}}</span>
</div>
<div class="col-6">
<span class="labelspan">{{ summaryform.numberofjobs.label }}</span>
{{ summaryform.numberofjobs.errors }}
<span class="inputfieldspan">{{ summaryform.numberofjobs}}</span>
</div>
</div>
{{ summaryform.message.help_text }}
<button type="submit" class="btn3">Save and Continue</button></form>
{% endblock %}
i need to take input in summary form and allow user to edit using the same view.when i save the filled data its updating but the main issue is its not populating data in the form from the database using instance.
Try
fields = ['summary','numberofprojects','numberofinternships','numberofjobs']
into forms.py