class Comments(models.Model):
comment_uuid = models.UUIDField(default=uuid.uuid4, editable=False)
language_post = models.ForeignKey(
PostInLanguages, null=False, related_name='comment_data', on_delete=models.CASCADE)
language = models.ForeignKey(
Languages, default=2, on_delete=models.CASCADE)
is_post_comment = models.BooleanField(default=True)
parent_post_comment_id = models.PositiveIntegerField(null=True)
user = models.ForeignKey(User, on_delete=models.CASCADE)
description = models.CharField(max_length=400, blank=False)
created_on = models.DateTimeField(default=timezone.now)
class Meta:
ordering = ["-created_on"]
indexes = [
models.Index(fields=['comment_uuid', 'parent_post_comment_id', 'is_post_comment', 'language_post']),
]
def __str__(self):
return '{}'.format(self.user)
def total_comment(self):
return self.language_post.count()
So the field parent post comment id will refer to comment on the same table
And is_post_comment field is a boolean field This means if the value is 1 then it's a comment on a post and if the value is 0 then it's a comment on another comment also when the comment is of another comment we have to provide parent_post_comment_id.
I'm trying to get the queryset of based on how many comments a comment has and also want to filter with minimum comments
And also want to know what will total comment method return as it will be called on only one object.
I have tried this but doesn't seem to work.
Comments.objects.annotate(Count('parent_post_comment_id')).filter(parent_post_comment_id__count__gte=minimum_comment,is_post_comment=False).values_list("parent_post_comment_id")[:100]
CodePudding user response:
If I got it right you need for each comment get quantity of related child comments. To do it in efficient way i would change your model because it doesn't have back relation from child comment to parent.
I would do this model in this way:
# The name of the model usually is singular
class Comment(models.Model):
# it's not clear if it's your primary key, if it's you need to
# put primary_key=True
comment_uuid = models.UUIDField(
default=uuid.uuid4,
editable=False,
primary_key=True
)
language_post = models.ForeignKey(
PostInLanguages,
null=False,
related_name='comment_data',
on_delete=models.CASCADE
)
language = models.ForeignKey(
Languages, default=2, on_delete=models.CASCADE)
# In my opinion this field is extra for your purposes
# you can filter if you model has or not children without it
# is_post_comment = models.BooleanField(default=True)
# to have back relation we should link our child comment
# record to our parent comment, it's 'self' related field so
parent_post_comment = models.ForeignKey(
'self',
null=True,
blank=True,
related_name='child',
on_delete=models.CASCADE
)
user = models.ForeignKey(User, on_delete=models.CASCADE)
description = models.CharField(max_length=400, blank=False)
created_on = models.DateTimeField(default=timezone.now)
So after you do this model in that way you can receive all comments with quantity of their children and filter it as you wish:
from django.db.models import Count
comments_q = Comment.objects.annotate(children_qty=Count('child')).all()
comments_only_with_childrens_q = comment_q.filter(children_qty__gt=0)
minimum_comments_amount = 1
comments_with_children_bigger_then = \
comment_q.filter(children_qty__gt=minimum_comments_amount)