Home > other >  I have this Django model "comments" i want to get the list of comments based on their link
I have this Django model "comments" i want to get the list of comments based on their link

Time:12-31


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)
  • Related