Django et les commentaires

Publié le 12 octobre 2008 par Mikebrant

On va essayer de mettre en place un système de commentaire sur notre site

Ces derniers jours j'arrête pas de me faire spammer sur qui-saura.

J'en profite donc pour passer au module comments de Django (j'utilisais avant un truc fait 'maison').
monProjet = monBlog
monApplication = partieBlog

 On commence donc par rajouter dans le tuple INSTALLED_APPS du fichier setting.py de notre projet Django : ( monBlog/setting.py)

 'django.contrib.comments',

Afin de dire à Django que l'on souhaite utiliser  son système de commentaires .
Il faut ensuite lancer ceci (monBlog/manage.py) :

python manage.py syncdb

Afin que Django crée notre table commentaires ( django_comments) .

Puis on rajoute dans le fichier urls de notre projet ceci : ( monBlog/urls.py)

(r'^commentaires/', include('django.contrib.comments.urls.comments')),


Maintenant, dans le template qui va se charger d'afficher un article en particulier, on ajoute ceci : (monBlog/partieBlog/templates/detail.html)

 {% load comments %}


Ca va nous permettre d'utiliser le fameux module comments .


Pour avoir des commentaires, encore faut-il avoir un formulaire pour poster un com .

comments propose un modèle de Formulaire : CommentForm tout prêt qui me plait bien :
il contient divers champs qui vont lutter contre le spam.
On va donc s'en servir .


Donc, toujours dans le même template, rajoutez :

  <form action="" method="POST">
  {% for field in formulaire %}
  {% if field.is_hidden %}
  {{ field }}
  {% else %}
  <p
  {% if field.errors %} class="error"{% endif %}
  {% ifequal field.name "honeypot" %} style="display:none;"{% endifequal %}>
  {% if field.errors %}{{ field.errors }}{% endif %}
  {{ field.label_tag }} {{ field }}
  </p>  
  {% endif %}
  {% endfor %}
  <input type="submit" name="submit" class="submit-post" value="Ok" />
 </form>


Cela va afficher notre formulaire.

Je n'explique pas ce qu'il y a à l'intérieur du for c'est trivial ( d'ailleurs, j'ai simplement recopié le fichier /usr[/local]/lib/python2.x/site-packages/django/contrib/comments/templates/comments/form.html ).

formulaireest la variable contenant notre CommentForm .
Elle est créée du côté de la vue(monBlog/partieBlog/views.py) : dans la fonction detail() qui retourne notre template.

Quand on validera notre commentaire, la page actuelle se rechargera, c'est aussi detail() qui va s'occuper de sauvegarder le commentaire ou non.

Voici donc detail() avant le tuto:


def detail(request, monBillet):
   """Montre un billet"""


   try:
        erreur = None
        billet = Billet.objects.get(lienTitre=monBillet)
   except:
        billet = None
        erreur = "Aucun billet de ce nom"
return render_to_response('detail.html', {'billet': billet, 'erreur': erreur})

Et voici detail() après :

from django.contrib.comments.views.comments import post_comment
from django.contrib.comments.forms import CommentForm
 
def detail(request, monBillet):
   """Montre un billet"""
   try:
      erreur = None
      reponse = ''
      billet = Billet.objects.get(lienTitre=monBillet)
      formulaire = CommentForm(billet)

      if request.method=='POST':
         donnees = request.POST.copy()
         formulaire = CommentForm(billet,donnees)
         if formulaire.is_valid():
            post_comment(request)
            formulaire = CommentForm(billet)
   
   except:
      billet = None
      erreur = "Aucun billet de ce nom"

return render_to_response('detail.html', {'billet': billet, 'erreur': erreur, 'formulaire':formulaire})


On commence par instancier la classe CommentForm, qui prend en paramètre obligatoire l'objet auquel il sera lié .
Si la requête est de type POST alors on a validé le formulaire : on rentre donc dans le if.
On copie la valeur des champs du formulaire dans donnees.
On réinstancie la classe CommentForm afin de lui mettre en paramètre donnees .
Si le formulaire est valide (cad que tous les champs sont remplis, etc.. ), alors on sauvegarde le commentaire via post_comment(), puis on crée un formulaire vide sinon on laisse le formulaire avec les erreurs.

Voilà le formulaire pour ajouter un commentaire est fini.

Il nous reste plus qu'à lister dans la page affichant un article les commentaires liés ...
Mais c'est super rapide : 
Rajoutez, toujours dans le même template, toujours après le {% load comments %}, mais avant le formulaire [ enfin je trouve que c'est bien mieux d'avoir les commentaires avant le formulaire ] , ceci :

 {% get_comment_list for partieBlog.billet billet.id as commentaire %}
  {% for com in commentaire %}
  <div class="commentaires">
  Posté par <strong>
  {% if com.user_url %}
  <a href="{{ com.user_url }}">{{ com.user_name }}</a></strong>, <em>{{com.submit_date|date:"l d F Y à H:i"}}</em>
  {% else %}
  {{ com.user_name }}</strong>, <em>{{com.submit_date|date:"l d F Y | H:i"}}</em>
  {% endif%}
  <br /><br />
  {{ com.comment|safe }}
  </div><br />
{% endfor %}

get_comment_list retourne une liste des commentaires liés au type billet ayant l'id billet.id .
Ensuite, on fait un for afin de tous les afficher en les formatant.

Et c'est terminé.
j'espère que j'aurais moins de spam...