I am building a simple question answer site, in which - I am trying to implement a like button But When i like the post then solid liked button is showing and blank liked button is also showing.
models.py
class Question(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
title= models.CharField(max_length=300)
class Answer(models.Model):
user_by = models.ForeignKey(User, on_delete=models.CASCADE)
que = models.ForeignKey(Question, on_delete=models.CASCADE)
body = models.CharField(max_length=300)
class LikeAnswer(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
ans = models.ForeignKey(Answer, on_delete=models.CASCADE)
views.py
def question_detail(request, question_id):
obj = get_object_or_404(Question, pk=question_id)
answers = obj.answer_set.all()
context = {'obj':obj,'answers':answers}
return render(request, 'question_detail.html', context)
quesion_detail.html
{{obj.title}}
{% for anss in answers %}
{% for lks in anss.likeanswer_set.all %}
{% if request.user == lks.user %}
<button name='submit' type='submit' id="unlike" value="unlike">Unlike
</button> <i class="fas fa-thumbs-up"></i>
{% else %}
<button name='submit' type='submit' id="like" value="like">
</button><i class="fal fa-thumbs-up"></i>
{% endif %}
{% endfor %}
{% endfor %}
What i am trying to do :-
I am trying to show only filled like button after user like, But it is showing both buttons.
I have also tried {% empty %} but it didn't made impact on it, It showed same results.
They are showing like :-
Any help would be much Appreciated. Thank You in Advance.
You are iterating over all likes, whether they are from the request user or not, and as soon as there is any other user, there will be also the "unlike" button, so you will have both buttons.
Related
I want to allow an user to be able to like an post only once. Here is my code so far:
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
likes = models.PositiveIntegerField(default=0)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('post-detail', kwargs={'pk': self.pk})
In views.py:
def LikePostView(request, pk):
post = get_object_or_404(Post, pk=pk)
post.likes = post.likes+1
post.save()
return render(request, 'blog/like_done.html')
Code to like a post on frontend:
<p class="content">{{ post.likes }} likes</p>
{% if user.is_authenticated %}
</i>
{% else %}
<a onclick="alert('In order to like a post, you must be logged in!')" href='{% url "blog-home" %}'><i class="fa fa-thumbs-up" style="font-size:36px"></i></a>
{% endif %}
And like_done.html:
{% extends "blog/base.html" %}
{% block content %}
<h2 class="alert alert-success">Post Liked Successfuly!</h2>
<br>
<a class="btn btn-success" href="{% url 'blog-home' %}">Go Back Home?</a>
<br>
{% endblock content %}
So with all this, how would I make the user be allowed to only like a post once. I am only beginner, so please explain a little.
If I get your question right, You want a user to be able to like a post once, and when the user clicks on the like button the second time it should 'unlike' right?
If so, this is what you should do:
In you Post model, the like should be like this likes = models.ManyToManyField(User, related_name='user_likes'), a ManyToManyField.
Then in your views:
def LikePostView(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.user in post.likes.all():
post.likes.remove(request.user)
else:
post.likes.add(request.user)
return render(request, 'blog/like_done.html')
This way if the user clicks the like button he will be added to the likes Field and if he clicks it again he will be removed seems he is already there. So the user won't be able to like a post more than once.
I'm making a quiz app in Django. It is a MCQ type of quiz app where users have to select the answer from a list of multiple answers.
Now, in my models.py there are three models:
Quiz
Question
Answer
Where Quiz model defines the type of quiz (For example Basic, Intermediate, Advance), Question model has a ForeignKey of Quiz to specify the type of question and a CharField to mention the text of the question. The Answer model is similar to Question model but with ForeignKey of Question to specify the question that answer is related to, CharField for the text of the answer and a BooleanField to specify if that answer is correct or not.
models.py
from django.db import models
# Create your models here.
class Quiz(models.Model):
q_name = models.CharField(max_length=30)
desc = models.CharField(max_length=100)
def __str__(self):
return self.q_name
class Question(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE)
label = models.CharField(max_length=1000)
def __str__(self):
return self.label
class Answer(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
text = models.CharField(max_length=1000)
is_correct = models.BooleanField(default=False)
def __str__(self):
return self.text
views.py
from django.shortcuts import render, redirect, reverse
from django.contrib import messages
from .models import Quiz, Question, Answer
def basic_quest(request, quiz_name, ques_no):
if request.method == "POST":
guess = request.POST.get('answer')
ans = Answer.objects.get(text = guess)
if ans.is_correct == True:
messages.success(request,("Correct"))
return redirect('basic_quest')
else:
messages.error(request,("Wrong"))
else:
question = Question.objects.get(id = ques_no)
answers = Answer.objects.filter(question = ques_no)
return render(request, 'quest.html', {'question' : question, 'answers' : answers})
quest.html
{% extends 'base.html' %}
{% block title %}
Question - Quiz Python
{% endblock title %}
{% block content %}
<div class="container">
{% if messages %}
{% for message in messages %}
<div class="alert alert-primary alert-dismissible fade show" role="alert">
{{ message }}
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
{% endfor %}
{% endif %}
<p><h1>{{ question.label }}</h1></p>
<form method="POST">
{% csrf_token %}
{% for answer in answers %}
<label><input type="radio" name="answer" value={{ answer.text }}> {{ answer.text }}</label>
</br>
{% endfor %}
<input type="submit">
</form>
</div>
{% endblock content %}
After selecting the answer using the radio button and clicking on submit I want it to display a message on the same page as correct or incorrect by checking the value of the radio button selected with the answer available in the Answer model.
But I'm getting the following error:
NoReverseMatch at /quiz/Basic/1
Reverse for 'basic_quest' with no arguments not found. 1 pattern(s) tried: ['quiz/(?P<quiz_name>[^/]+)/(?P<ques_no>[^/]+)$']
Request Method: POST
Request URL: http://localhost:8000/quiz/Basic/1
Django Version: 2.2.7
Exception Type: NoReverseMatch
Exception Value:
Reverse for 'basic_quest' with no arguments not found. 1 pattern(s) tried: ['quiz/(?P<quiz_name>[^/]+)/(?P<ques_no>[^/]+)$']
Exception Location: /Users/apple/Desktop/myvenv/quiz/lib/python3.7/site-packages/django/urls/resolvers.py in _reverse_with_prefix, line 673
Python Executable: /Users/apple/Desktop/myvenv/quiz/bin/python
Python Version: 3.7.4
Python Path:
['/Users/apple/Desktop/quiz',
'/Library/Frameworks/Python.framework/Versions/3.7/lib/python37.zip',
'/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7',
'/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload',
'/Users/apple/Desktop/myvenv/quiz/lib/python3.7/site-packages']
I'm currently attempting to modify a page that essentially keeps track of when a user enters/leaves an area. Currently all the logic works fine, but I would like to add the functionality to ask a user to enter their own estimate of the time they entered/left in the case they forgot to do so, since these instances get flagged upon submission.
What I'm having trouble with, is actually getting the "popup" to display. I'm not sure how to accomplish this from the views.py, where I added the comment. I guess I need a way to just render that extra html on top of the page, without refreshing, until after they submit the edited_timestamp. I'm fairly new to Django/Python, and I have a very basic understanding of how this all works, so I apologize in advance if my suggestions on handling this are a bit off.
These is a summarized version of what the models look like:
models.py
class EmployeeWorkAreaLog(TimeStampedModel, SoftDeleteModel, models.Model):
employee_number = models.ForeignKey(Salesman, on_delete=models.SET_NULL, help_text="Employee #", null=True, blank=False)
work_area = models.ForeignKey(WorkArea, on_delete=models.SET_NULL, null=True, blank=False, help_text="Work Area", related_name="work_area")
station_number = models.ForeignKey(StationNumber, on_delete=models.SET_NULL, null=True, help_text="Station", related_name="stations", blank=True)
edited_timestamp = models.DateTimeField(null=True, blank=True)
time_exceptions = models.CharField(max_length=2, blank=True)
time_in = models.DateTimeField(help_text="Time in", null=True, blank=True)
time_out = models.DateTimeField(blank=True, help_text="Time out", null=True)
def __str__(self):
return self.employee_number
I figured that the easiest way to do this is by adding it to the logic in views.py, to prevent updating a wrong record, in such a way that, right after an entry gets flagged, the user is prompted to enter the date/time they estimate they entered an area.
To keep code readable, I'm only showing the case where entries get flagged. If someone tries to enter any area, the forgets to exit, and then attempts to enter an area again, the record without an exit gets immediately flagged (the time_exceptions='N' is the flag).
views.py
class EnterExitArea(CreateView):
model = EmployeeWorkAreaLog
template_name = "operations/enter_exit_area.html"
form_class = WarehouseForm
def form_valid(self, form):
emp_num = form.cleaned_data['employee_number']
area = form.cleaned_data['work_area']
station = form.cleaned_data['station_number']
if 'enter_area' in self.request.POST:
form.save()
EmployeeWorkAreaLog.objects.filter((Q(employee_number=emp_num) & Q(work_area=area) & Q(time_out__isnull=True) & Q(time_in__isnull=True)) & (Q(station_number=station) | Q(station_number__isnull=True))).update(time_in=datetime.now())
# If employee has an entry without an exit and attempts to enter a new area, mark as an exception 'N'
if EmployeeWorkAreaLog.objects.filter(Q(employee_number=emp_num) & Q(time_out__isnull=True) & Q(time_exceptions="")).count() > 1:
first = EmployeeWorkAreaLog.objects.filter(employee_number=emp_num, time_out__isnull=True).order_by('-time_in').first()
EmployeeWorkAreaLog.objects.filter((Q(employee_number=emp_num) & Q(time_out__isnull=True))).exclude(pk=first.pk).update(time_exceptions='N')
# Here would be the rendering of the page, maybe as a popup? and then saving the entered field using edited = form.cleaned_data['edited_timestamp'] and then saving it using .update()
return HttpResponseRedirect(self.request.path_info)
I was trying to do this in a way that instead of redirecting to the same page, it would render something similar to the page below, which just requests for the time, and after the user submits, it saves it into the records' edited_timestamp field.
update_edited_timestamp.html
<div>
<form id="warehouseForm" action="" method="POST" class="form-horizontal">
<label>Enter estimated time:</label>
<input value="html()" type="datetime-local" name="edited_timestamp">
</form>
</div>
Adding my main html page where this all takes place just in case. When the person hits the "Enter" button, it's when the logic in views starts.
enter_exit_area.html
{% extends "operations/base.html" %}
{% block main %}
<form id="warehouseForm" action="" method="POST" class="form-horizontal" novalidate >
{% csrf_token %}
<div>
<div>
<div style="color: red">{{ form.employee_number.errors.as_text }}</div>
<label>Employee</label>
{{ form.employee_number }}
</div>
<div>
<div style="color: red">{{ form.work_area.errors.as_text }}</div>
<label>Work Area</label>
{{ form.work_area }}
</div>
<div style="color: red">{{ form.station_number.errors.as_text }}</div>
<div>
<label>Station</label>
{{ form.station_number }}
</div>
</div>
<div>
<div>
<button type="submit" name="enter_area" value="Enter">Enter Area</button>
<button type="submit" name="leave_area" value="Leave">Leave Area</button>
</div>
</div>
</form>
{% endblock main %}
I'm trying to modify a page that essentially keeps tracks of when users enter/leave an area. Currently all the logic works fine, but I would like to add the functionality to ask a user to enter their own "estimate" of the time they entered/left in the case they forgot to do so, since these instances get flagged upon submission. I'm fairly new to Django/Python, and I have a very basic understanding of how this all works, so I apologize in advance if my suggestions on handling this are a bit off.
These is a summarized version of what the models look like:
models.py
class EmployeeWorkAreaLog(TimeStampedModel, SoftDeleteModel, models.Model):
employee_number = models.ForeignKey(Salesman, on_delete=models.SET_NULL, help_text="Employee #", null=True, blank=False)
work_area = models.ForeignKey(WorkArea, on_delete=models.SET_NULL, null=True, blank=False, help_text="Work Area", related_name="work_area")
station_number = models.ForeignKey(StationNumber, on_delete=models.SET_NULL, null=True, help_text="Station", related_name="stations", blank=True)
edited_timestamp = models.DateTimeField(null=True, blank=True)
time_exceptions = models.CharField(max_length=2, blank=True)
time_in = models.DateTimeField(help_text="Time in", null=True, blank=True)
time_out = models.DateTimeField(blank=True, help_text="Time out", null=True)
def __str__(self):
return self.employee_number
I figured that the easiest way to do this is by adding it to the logic in views.py, to prevent updating a wrong record, in such a way that, right after an entry gets flagged, the user is prompted to enter the date/time they estimate they entered an area.
To keep code readable, I'm only showing the case where entries get flagged. If someone tries to enter any area, the forgets to exit, and then attempts to enter an area again, the record without an exit gets immediately flagged (the time_exceptions='N' is the flag).
views.py
class EnterExitArea(CreateView):
model = EmployeeWorkAreaLog
template_name = "operations/enter_exit_area.html"
form_class = WarehouseForm
def form_valid(self, form):
emp_num = form.cleaned_data['employee_number']
area = form.cleaned_data['work_area']
station = form.cleaned_data['station_number']
if 'enter_area' in self.request.POST:
form.save()
EmployeeWorkAreaLog.objects.filter((Q(employee_number=emp_num) & Q(work_area=area) & Q(time_out__isnull=True) & Q(time_in__isnull=True)) & (Q(station_number=station) | Q(station_number__isnull=True))).update(time_in=datetime.now())
# If employee has an entry without an exit and attempts to enter a new area, mark as an exception 'N'
if EmployeeWorkAreaLog.objects.filter(Q(employee_number=emp_num) & Q(time_out__isnull=True) & Q(time_exceptions="")).count() > 1:
first = EmployeeWorkAreaLog.objects.filter(employee_number=emp_num, time_out__isnull=True).order_by('-time_in').first()
EmployeeWorkAreaLog.objects.filter((Q(employee_number=emp_num) & Q(time_out__isnull=True))).exclude(pk=first.pk).update(time_exceptions='N')
# Here would be the rendering of the page, maybe as a popup? and then saving the entered field using edited = form.cleaned_data['edited_timestamp'] and then saving it using .update()
return HttpResponseRedirect(self.request.path_info)
I was trying to do this in a way that instead of redirecting to the same page, it would render something similar to the page below, which just requests for the time, and after the user submits, it saves it into the records' "edited_timestamp" field.
update_edited_timestamp.html
<div>
<form id="warehouseForm" action="" method="POST" class="form-horizontal">
<label>Enter estimated time:</label>
<input value="html()" type="datetime-local" name="edited_timestamp">
</form>
</div>
Adding my main html page where this all takes place just in case
enter_exit_area.html
{% extends "operations/base.html" %}
{% block main %}
<form id="warehouseForm" action="" method="POST" class="form-horizontal" novalidate >
{% csrf_token %}
<div>
<div>
<div style="color: red">{{ form.employee_number.errors.as_text }}</div>
<label>Employee</label>
{{ form.employee_number }}
</div>
<div>
<div style="color: red">{{ form.work_area.errors.as_text }}</div>
<label>Work Area</label>
{{ form.work_area }}
</div>
<div style="color: red">{{ form.station_number.errors.as_text }}</div>
<div>
<label>Station</label>
{{ form.station_number }}
</div>
</div>
<div>
<div>
<button type="submit" name="enter_area" value="Enter">Enter Area</button>
<button type="submit" name="leave_area" value="Leave">Leave Area</button>
</div>
</div>
</form>
{% endblock main %}
I'm making my own blog with Django and I already made a Comments system.. I want to add the replies for each comment (like a normal comment's box) and I don't know what to do this is my current models.py comments:
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)
parent = models.ForeignKey('self', null=True, related_name='replies')
def __str__(self):
return self.text
and this is the .html where I use the comments
{% for comment in post.comments.all %}
<ul>
{{ comment.text }}
{% for reply in comment.replies.all %}
<li>
{{ reply.text }}
</li>
{% endfor %}
<ul>
{% endfor %}
and apparently It is working but when I try to make a comment in the admin site of Django it forces me to put a "Parent" to each comment (and this is not obligatory beacuse not every comment is a reply) I also don't know how to add the reply "button" in the HTML file. Please help tell me what changes can I do to make a simple comment box with replies . Thanks a lot
I had the same problem and resolved it as follows:
1.
For admin site as mentioned above just set blank=True for parent field. My comment model:
class Comment(models.Model):
post = models.ForeignKey(Post, related_name='comments')
name = models.CharField(max_length=80)
email = models.EmailField(max_length=200, blank=True)
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
# manually deactivate inappropriate comments from admin site
active = models.BooleanField(default=True)
parent = models.ForeignKey('self', null=True, blank=True, related_name='replies')
class Meta:
# sort comments in chronological order by default
ordering = ('created',)
def __str__(self):
return 'Comment by {}'.format(self.name)
remember to run makemigrations and migrate
2.Let's start with views. I'm using the post_detail
view to display the post and its comments. We add a QuerySet to retrieve all parent active comments for this post. After this, we validate the submitted data using the form's is_valid(). If the form is valid we check if submitted data comes from hidden input in replay button form. Next if parent_id exits we create parent object(parent_obj) for replay comment and replay_comment object, then we assign parent_obj to replay_comment.
If parent_obj is equal to None we just proceed with normal comment by creating new_comment object and saving it to the database.
def post_detail(request, post):
# get post object
post = get_object_or_404(Post, slug=post)
# list of active parent comments
comments = post.comments.filter(active=True, parent__isnull=True)
if request.method == 'POST':
# comment has been added
comment_form = CommentForm(data=request.POST)
if comment_form.is_valid():
parent_obj = None
# get parent comment id from hidden input
try:
# id integer e.g. 15
parent_id = int(request.POST.get('parent_id'))
except:
parent_id = None
# if parent_id has been submitted get parent_obj id
if parent_id:
parent_obj = Comment.objects.get(id=parent_id)
# if parent object exist
if parent_obj:
# create replay comment object
replay_comment = comment_form.save(commit=False)
# assign parent_obj to replay comment
replay_comment.parent = parent_obj
# normal comment
# create comment object but do not save to database
new_comment = comment_form.save(commit=False)
# assign ship to the comment
new_comment.post = post
# save
new_comment.save()
return HttpResponseRedirect(post.get_absolute_url())
else:
comment_form = CommentForm()
return render(request,
'core/detail.html',
{'post': post,
'comments': comments,
'comment_form': comment_form})
Simple comment form:
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ('name', 'email', 'body')
* More about ModelForm
And lastly template. We need to create two forms. One form for comments and the second one for replays. Here you have simple template:
<!-- Comments Form -->
<h2>Add a new comment</h2>
<form action="." method="post">
{{ comment_form.as_p }}
{% csrf_token %}
<button type="submit">Add comment</button>
</form>
<!-- Comment with nested comments -->
{% for comment in comments %}
<div class="comment" style="background-color: powderblue">
<p class="info">{{ comment.name }} | {{ comment.created }}</p>
{{ comment.body|linebreaks }}
{% for replay in comment.replies.all %}
<p class="info">{{ replay.name }} | {{ replay.created }}</p>
<li>{{ replay.body }}</li>
{% endfor %}
<h5>Replay</h5>
<form action="." method="post">
{{ comment_form.as_p }}
{% csrf_token %}
<!-- Hidden input for parent comment.id -->
<input type="hidden" name="parent_id" value="{{ comment.id }}">
<input class="btn btn-primary" type="submit" value="Replay">
</form>
</div>
{% empty %}
<h4>There are no comments yet.</h4>
{% endfor %}
just add some nice css and maybe jquery to have fade in reply comments and that's all.
first Question:parent must be set in admin.
parent = models.ForeignKey('self', null=True, blank=True, related_name='replies')
blank=True can let you don't set parent in admin.
second Question:add comment dynamicly.
<form id="comment-form" method="post" role="form">
{% csrf_token %}
<textarea id="comment" name="comment" class="form-control" rows="4" placeholder="input comment!"></textarea>
<button type="submit" class="btn btn-raised btn-primary pull-right">submit</button>
</form>
$('#comment-form').submit(function(){
$.ajax({
type:"POST",
url:"{% url 'article_comments' article.en_title %}",
data:{"comment":$("#comment").val()},
beforeSend:function(xhr){
xhr.setRequestHeader("X-CSRFToken", $.cookie('csrftoken'));
},
success:function(data,textStatus){
$("#comment").val("");
$(".comment ul").prepend(data);
},
error:function(XMLHttpRequest, textStatus, errorThrown){
alert(XMLHttpRequest.responseText);
}
});
return false;
});
view.py:
print_comment = u"<p>comment:{}</p>".format(text)
if parent:
print_comment = u"<div class=\"comment-quote\">\
<p>\
<a>#{}</a>\
{}\
</p>\
</div>".format(
parent.user.username,
parent.text
) + print_comment
# current comment
html = u"<li>\
<div class=\"comment-tx\">\
<img src={} width=\"40\"></img>\
</div>\
<div class=\"comment-content\">\
<a><h1>{}</h1></a>\
{}\
<p>{}</p>\
</div>\
</li>".format(
img,
comment.user.username,
print_comment,
datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
)
return HttpResponse(html)
models.py
class Comment(models.Model):
author = models.CharField(max_length=100)
comment_field = models.TextField()
date_created = models.DateTimeField(auto_now_add=True)
post = models.ForeignKey('Post', on_delete=models.CASCADE)
reply = models.ForeignKey('Comment', on_delete=models.CASCADE, related_name="replies", null=True)
def __str__(self):
return self.author
views.py
def post_detail(request, slug):
post = Post.objects.get(slug=slug)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
reply_obj = None
try:
reply_id = int(request.POST.get('reply_id'))
except:
reply_id = None
if reply_id:
reply_obj = Comment.objects.get(id=reply_id)
author = form.cleaned_data['author']
comment = form.cleaned_data['comment']
if reply_obj:
Comment(author=author,comment_field=comment, reply=reply_obj, post=post).save()
else:
Comment(author=author,comment_field=comment, post=post).save()
return redirect(reverse('post_detail', args=[post.slug]))
else:
form = CommentForm()
comments = Comment.objects.filter(post=post, reply=None).order_by('-date_created')
context = {
'post':post,
'form':form,
'comments':comments
}
return render(request, 'post_detail.html', context)
template (post_detail.html)
{% for comment in comments %}
{{comment.author}}
{{comment.date_created.date}}
{{comment.comment_field}}
{% for reply in comment.replies.all %}
{{reply.author}}
{{reply.date_created.date}}
{{reply.comment_field}}
{% endfor %}
<a class="text-decoration-none" data-bs-toggle="collapse" href="#collapseExample{{comment.id}}" role="button" aria-expanded="false" aria-controls="collapseExample">
Reply </a>
<div class="collapse" id="collapseExample{{comment.id}}">
<div>
<form action="" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="form-group">
{{ form.author }}
</div>
<div class="form-group mt-md-2">
{{form.comment}}
</div>
<input type="hidden" name="reply_id" value="{{ comment.id }}">
<button class="btn btn-primary mt-md-1" type="submit" value="Reply">Reply</button> </form>
</div>
</div>
<hr>
{% endfor %}
You need to create a field called parent which is a ForeignKey with the Comment model itself.
parent = models.ForeignKey('self' , null=True , blank=True , on_delete=models.CASCADE , related_name='replies')
Also, you can create a property called children in the Comment model which returns all the replies of the comment.
#property
def children(self):
return BlogComment.objects.filter(parent=self).reverse()
For detail explanation of comment and reply system in django you can read my article about that.