Nested comments in django

#1

Hi everyone!

What is the best choice to do nested comments in django?

This is my comments model

class Comment(models.Model):
    article = models.ForeignKey(Article, on_delete=models.CASCADE, related_name='comment', verbose_name=_('Article'))
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, verbose_name=_('User'))
    message = models.TextField(max_length=1500, verbose_name=_('Message'))
    timestamp = models.DateTimeField(auto_now_add=True, verbose_name=_('Created at'))
    parent = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, verbose_name=_('Parent comment'))
    is_approved = models.BooleanField(default=True, verbose_name=_('Is approved'))

And I can print comments in template something like

{% for comment in comments %}
    {% if not comment.parent %}
        {{ comment.user }} said: {{ comment.message }}
            {% for child in comments %}
                {% if comment.pk == child.parent.pk %}
                    {{ child.user }} answered to {{ comment.user }}: {{ child.message }}
                {% endif %}
            {% endfor %}
    {% endif %}
{% endfor %}

But in this case it doesn’t show answer comments to child comment and more deeper comments in tree.

Is it possible to make something like that without using any additional libraries?
If not, is django-mptt the best way to do it? Or another better library exist?

Thanks for answers.

0 Likes

(Arvie San) #2

It will be easier if you will create a model manager for it:

class CommentManager(models.Manager):
"""Model manager for `Comment` model."""

def all(self):
    """Return results of instance with no parent (not a reply)."""
    qs = super().filter(parent=None)
    return qs

So you will get all the comments by default.

class Comment(models.Model):
"""Model for comments."""

def children(self):
    """Return replies of a comment."""
    return Comment.objects.filter(parent=self)

@property
def is_parent(self):
    """Return `True` if instance is a parent."""
    if self.parent is not None:
        return False
    return True

You can also create methods inside the model so you can do this in the templates:

{% for reply in comment.children %}
{% endfor %}

You can check this for the entire tutorial but it uses generic relations: django comments

2 Likes

#3

Thanks. But in this situation I don’t know how to print out deeper comments in tree.
Finally, installed django-mptt.

0 Likes

(Basil Jose) #4

You may refer Django Threaded Comments

1 Like