I have an app which essentially a conversation system (much like reddit).
Where a post can have multiple replies, and a reply and have multiplies, and a reply to a reply can have multiple replies (etc.)
I’ve made the model like this:
class Discussion(models.Model):
message = models.TextField()
replies = models.ManyToManyField('self')
and the view:
discussions = Discussions.objects.all()
and the template looks like this:
{% for discussion in discussions %}
{{ discussion.message }}
{% endfor %}
How would I go about making a system where I can output all replies like this?
discussion
reply
reply
reply
reply
reply
reply
Which would go down as far as it needs to to ensure all replies are listed.
Unless a reply can be a reply to multiple posts, a
ManyToManyFieldisn’t what you want. You just need aForeignKey:Then you can get to a Discussion’s replies with
Discussion.replies.Unfortunately, there’s no way to do a recursion in Django’s template language, so you have to either 1) run a recursive function to get a “flattened” list of replies, and put that in the context, or 2) write a function that can be called recursively that uses a template to generate each level, which would look something like:
Then in your top-level template, you just need:
Apply CSS as desired to make it look nice.
EDIT: Root discussions are those in
Discussion.objects.filter(reply_to=None). And all the code,_DiscussionTemplateincluded, goes in yourmodels.py. This way,_DiscussionTemplateis initialized once when the module loads.EDIT 2: Putting the HTML in a template file is pretty straightforward. Change the view code that sets
_DiscussionTemplateto:Then create
discussiontemplate.html:Set the path to the template file as needed.