À moins qu'une réponse puisse être une réponse à plusieurs messages, un ManyToManyField
n'est pas ce que vous voulez. Vous avez juste besoin d'un ForeignKey
:
class Discussion(models.Model):
message = models.TextField()
reply_to = models.ForeignKey('self', related_name='replies',
null=True, blank=True)
Ensuite, vous pouvez obtenir les réponses de une discussion avec Discussion.replies
.Malheureusement, il n'y a pas moyen de faire une récursion dans le langage template de Django, donc vous devez soit 1) exécuter une fonction récursive pour obtenir une liste de réponses "aplatie", et mettre cela dans le contexte, soit 2) écrire une fonction qui peut être appelée récursive qui utilise un modèle pour générer chaque niveau, ce qui ressemblerait à quelque chose comme:
_DiscussionTemplate = Template("""
<li>{{ discussion.message }}{% if replies %}
<ul>
{% for reply in replies %}
{{ reply }}
{% endfor %}
</ul>
{% endif %}</li>
""".strip())
class Discussion(models.Model):
message = models.TextField()
reply_to = models.ForeignKey('self', related_name='replies',
null=True, blank=True)
@property
def html(self):
return _DiscussionTemplate.render(Context({
'discussion': self,
'replies': [reply.html() for reply in self.replies.all()]
}))
Ensuite, dans votre modèle de haut niveau, il vous suffit:
<ul>
{% for d in discussions %}
{{ d.html }}
{% endfor %}
</ul>
Appliquer CSS comme désiré pour le rendre joli.
EDIT: Les discussions racine sont celles de Discussion.objects.filter(reply_to=None)
. Et tout le code, _DiscussionTemplate
inclus, va dans votre models.py
. De cette manière, _DiscussionTemplate
est initialisé une fois lorsque le module est chargé.
EDIT 2: Mettre le code HTML dans un fichier modèle est assez simple. Modifiez le code de la vue qui définit _DiscussionTemplate
à:
_DiscussionTemplate = loader.get_template("discussiontemplate.html")
Ensuite, créez discussiontemplate.html
:
<li>{{ discussion.message }}{% if replies %}
<ul>
{% for reply in replies %}
{{ reply }}
{% endfor %}
</ul>
{% endif %}</li>
Définissez le chemin du fichier de modèle au besoin.
Où va _DiscussionTemplate? Est-ce dans mon modèle? Dois-je importer le modèle? – dotty
symmetrical = Faux vomir une erreur donc je l'ai enlevé, cela fonctionnera-t-il encore? – dotty
Comment puis-je savoir quelles sont les discussions racine? – dotty