Partage
  • Partager sur Facebook
  • Partager sur Twitter

<Django> Venez commenter mon code de Mini-Chat

    10 juillet 2010 à 22:41:39

    Salut à tous,
    je débute dans l'utilisation de Django et je souhaite recevoir vos commentaires sur mon code de Mini-Chat, s'il-vous-plaît.

    Je fais les mêmes TPs que j'ai fait en PHP, sauf que, cette fois, j'utilise Django.

    Voici mes fichiers :

    sdz/urls.py


    # -*- coding: utf-8 -*-
    from django.conf.urls.defaults import *
    
    urlpatterns = patterns('sdz.chat.views',
        (r'^chat/$', 'index'), #La page d'index.
        (r'^chat/page/(?P<page>\d+)/$', 'index'), #Si une page est indiquée dans l'URL.
    )
    

    sdz/chat/models.py


    # -*- coding: utf-8 -*-
    from django.db import models
    from django.core.paginator import Paginator, InvalidPage, EmptyPage
    from django.forms import ModelForm
    
    class Chat(models.Model): #Cette table contiendra les messages des utilisateurs.
        pseudo = models.CharField(max_length = 50) #Un champ pour le pseudo.
        message = models.TextField() #Et un pour le texte.
        
        def __unicode__(self):
            return self.pseudo + ' - ' + self.message
        
        @staticmethod
        def obtenirDerniersMessages(page): #Cette méthode retourne les dix derniers messages de la page demandée.
            listeMessages = Chat.objects.all().order_by('-id')
            paginateur = Paginator(listeMessages, 10) #Paginer avec 10 messages par page.
            
            try:
                derniersMessages = paginateur.page(page)
            except(EmptyPage, InvalidPage):
                derniersMessages = paginateur.page(1)
            return derniersMessages
    
    class ChatForm(ModelForm):
        class Meta:
            model = Chat
    

    sdz/chat/views.py


    # -*- coding: utf-8 -*-
    from django.shortcuts import render_to_response
    from django.template import RequestContext
    from sdz.chat.models import Chat, ChatForm
    
    def index(request, page = 1):
        message = None
        if request.method == 'POST': #Si le formulaire a été soumis.
            formulaire = ChatForm(request.POST) #Un formulaire lié au données postées.
            
            if formulaire.is_valid(): #Si le formulaire est valide.
                m = formulaire.save(); #Retourne une instance du formulaire validé et enregistre les données.
                
                formulaire = ChatForm(initial = {'pseudo' : m.pseudo}) #Remplir le champ pseudo du formulaire pour qu'il n'y ait plus besoin d'écrire le pseudo.
                
                message = 'Votre message a été posté avec succès.'
        else:
            formulaire = ChatForm()
        #Et on affiche les derniers messages en plus d'un message dans le cas où l'utilisateur a posté un message.
        derniersMessages = Chat.obtenirDerniersMessages(page)
        return render_to_response('chat/index.html', {'formulaire' : formulaire, 'derniersMessages' : derniersMessages, 'message' : message}, context_instance = RequestContext(request))
    

    sdz/templates/chat/index.html


    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" >
        <head>
            <title>Mini-Chat</title>
            <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        </head>
        <body>
            <p><a href="{% url chat.views.index %}">Actualiser</a></p>
            
            <!-- S'il y a un message à afficher, on l'affiche ! -->
            {% if message %}
                <p><strong>{{ message }}</strong></p>
            {% endif %}
            
            <!-- Formulaire. -->
            <form method="post">
                {% csrf_token %}
                {% for champ in formulaire %}<!-- Parcourir tous les champs du formulaire. -->
                    <p>
                        {% if champ.errors %}<span style="color: red;">* </span>{% endif %} <!-- S'il y a une erreur, on affiche une étoile rouge. -->
                        {{ champ.label_tag }} :<!-- Affichage du nom du champ, suivi de deux-points. -->
                        
                        {{ champ }} <!-- Affichage du champ. -->
                    </p>
                {% endfor %}
                <input type="submit" value="Envoyer !"/>
            </form>
            
            <!-- Affichage des liens précédents, suivants, ... -->
            <p>
            {% if derniersMessages.has_previous %}
                <a href="{% url chat.views.index page=1 %}">&lt;&lt;</a>&nbsp;
                <a href="{% url chat.views.index page=derniersMessages.previous_page_number %}">&lt;</a>&nbsp;&nbsp;-&nbsp;
            {% endif %}
            
            <strong>Page {{ derniersMessages.number }} de {{ derniersMessages.paginator.num_pages }}</strong>
            
            {% if derniersMessages.has_next %}
                &nbsp;-&nbsp;&nbsp;<a href="{% url chat.views.index page=derniersMessages.next_page_number %}">&gt;</a>
                &nbsp;<a href="{% url chat.views.index page=derniersMessages.paginator.num_pages %}"> &gt;&gt;</a>
            {% endif %}
            </p>
            
            <!-- Affichage des derniers messages. -->
            <p>Derniers messages :</p>
            <p>
            {% for message in derniersMessages.object_list %}
                <p><strong>{{ message.pseudo|capfirst }} : </strong> {{ message.message|capfirst|linebreaksbr }}</p>
            {% empty %}
                <p>Aucun message pour le moment.<br/>Ajoutez-en un !</p>
            {% endfor %}
            </p>
            
            <!-- Affichage des liens précédents, suivants, ... -->
            <p>
            {% if derniersMessages.has_previous %}
                <a href="{% url chat.views.index page=1 %}">&lt;&lt;</a>&nbsp;
                <a href="{% url chat.views.index page=derniersMessages.previous_page_number %}">&lt;</a>&nbsp;&nbsp;-&nbsp;
            {% endif %}
            
            <strong>Page {{ derniersMessages.number }} de {{ derniersMessages.paginator.num_pages }}</strong>
            
            {% if derniersMessages.has_next %}
                &nbsp;-&nbsp;&nbsp;<a href="{% url chat.views.index page=derniersMessages.next_page_number %}">&gt;</a>
                &nbsp;<a href="{% url chat.views.index page=derniersMessages.paginator.num_pages %}"> &gt;&gt;</a>
            {% endif %}
            </p>
        </body>
    </html>
    


    J'ai mis beaucoup de commentaires pour que vous puissiez vous repérer plus facilement.

    Si vous ne savez pas trop par où commencer, j'ai des questions auxquelles vous pourriez peut-être me répondre :
    Est-ce correct de créer une méthode qui n'est pas une vue dans le fichier views.py ?


    Dans les templates, y a-t-il un moyen de ne pas avoir à écrire les URLs au complet (http://localhost:8000/chat/) dans les liens (en PHP, je n'avais pas ce genre de problèmes, car l'URL représentait un lien vers un fichier) ?


    Merci d'avance pour votre aide.
    • Partager sur Facebook
    • Partager sur Twitter
      10 juillet 2010 à 22:58:47

      Utilise déjà les forms de Django, ça permet d'éviter ce genre de magouilles (if(pseudo != '' and message != '') ) et ça offre une sécurité supplémentaire.
      Ensuite, plutôt que d'écrire tes paths en "brut", utilise plutôt le template tag "url" ({% url lien.vers.ta.vue.du.urls %}). Et sinon oui, certains créent des fonctions qui ne sont pas des vues dans views.py, mais si ça te démange, tu peux toujours rajouter un fichier à part dans l'application (functions.py par ex), sauf qu'ici, la fonction aurait plus sa place comme méthode du model Chat.
      • Partager sur Facebook
      • Partager sur Twitter
        11 juillet 2010 à 0:31:25

        Merci d'avoir pris le temps de regarder mon code et de me répondre.
        Je vais modifier cela.

        Si vous avez d'autres remarques, n'hésitez pas !

        Merci d'avance pour vos commentaires.
        • Partager sur Facebook
        • Partager sur Twitter
          12 juillet 2010 à 16:53:18

          Salut,
          j'ai modifié le code selon tes conseils (j'ai édité le premier message).

          Pouvez-vous me dire s'il y a d'autres choses à améliorer, s'il-vous-plaît ?

          J'ai encore des questions :
          Ma façon de retenir le pseudo est-elle bonne ?

          Pour rappel, la voici :
          formulaire = ChatForm(initial = {'pseudo' : pseudo})
          

          Je crée un nouveau formulaire : est-ce approprié ?

          Les erreurs sont en anglais (This field is required.).
          Y a-t-il un moyen de les traduire (un template, par exemple) ?


          J'ai cherché sur Internet des moyens de rendre mon Mini-Chat plus interactif (AJAX) et je me demande ce que vous me conseillerez comme bibliothèque AJAX en python sachant que je n'ai aucune connaissance en AJAX et que je souhaite le moins possible utiliser le javascript.

          Une qui m'intéresse est Pyjamas, mais je n'ai jamais réussi à l'installer - que pensez-vous de celle-ci (ou de GWT) ?
          Est-ce possible d'actualiser automatiquement ma page faite avec Django avec GWT ou Pyjamas ?

          Merci d'avance pour votre aide.
          • Partager sur Facebook
          • Partager sur Twitter
            12 juillet 2010 à 17:19:46

            Ca peut se faire ainsi pour le pseudo, je vois pas le problème. Ton code est un peu redondant avec les return, tu peux simplifier. Par contre, tu peux simplifier la création d'entrée de la base de données, vu que tu as un ModelForm :
            form.save()
            Ca créera une nouvelle entrée avec les données du formulaire (ça t'évite quelques lignes).

            Ensuite, pour avoir les erreurs en français, tu peux activer l'internalisation (i18n), je te laisse chercher de ce coté là. ;)

            Pour les url, je ne vois pas le problème vu que tu utilises url. Mais sinon, tu peux très bien utiliser un chemin relatif, ça s'utilise exactement comme en PHP.
            • Partager sur Facebook
            • Partager sur Twitter
              12 juillet 2010 à 18:41:13

              Tu peux aussi faire une inclusion de gabarit.
              Un pour le squelette html de ton site. L'autre l'incluera et tu ne modifieras que les blocks qui t'interressent ;)
              • Partager sur Facebook
              • Partager sur Twitter
                13 juillet 2010 à 5:27:43

                Bonsoir (et bonne nuit pour certains :D ).

                Encore une fois, merci pour ta réponse, MathX ; ça fait toujours plaisir de recevoir de tels commentaires.

                Et merci à devil may cry pour l'information sur l'inclusion de template.
                Sauf que je crois qu'ici, ce ne sera pas très utile.
                Mais, dans un vrai projet, ce sera nécessaire :)

                J'ai de nouveau éditer mon premier message.

                Pour avoir les erreurs en français, la seule chose que j'ai trouvée est de modifier ceci (dans settings.py) :
                LANGUAGE_CODE = 'en-us'
                

                En cela :
                LANGUAGE_CODE = 'fr-ca'
                

                Est-ce la bonne façon ?

                Pour les URLs relatives, comment faut-il faire ?
                La seule chose que j'ai trouvée est de remplacer tous les :
                sdz.chat.views

                en ceci :
                chat.views

                N'y a-t-il pas moyen de faire encore plus court ?
                Par exemple en donnant un nom dans le URLConf aux vues ?

                Concernant ces deux problèmes, je n'ai pas trouvé grand chose sur djangoproject...

                Si vous avez d'autres commentaires à faire, n'hésitez pas !

                Merci d'avance pour vos réponses.
                • Partager sur Facebook
                • Partager sur Twitter
                  13 juillet 2010 à 14:48:52

                  Il me semble que le point représente une url relative.

                  Exemple : <form action="." ...> Ce code renvoie sur la page courante.

                  Tu peux peut être t'en servir pour choisir une page du même dossier.
                  <a href="./tapage"> ou peut être <a href="./../tapage">
                  • Partager sur Facebook
                  • Partager sur Twitter
                    13 juillet 2010 à 16:30:29

                    Salut,
                    je voulais dire en utilisant la balise url :
                    <a href="{% url index %}">
                    

                    Ça fonctionne en modifiant le URLConf comme ceci :
                    # -*- coding: utf-8 -*-
                    from django.conf.urls.defaults import *
                    
                    urlpatterns = patterns('sdz.chat.views',
                        (r'^chat/$', 'index', {}, 'index'), #La page d'index.
                        (r'^chat/page/(?P<page>\d+)/$', 'index', {}, 'index.page'), #Si une page est indiquée dans l'URL.
                    )
                    

                    Si j'ajoute un nom à la page, je peux l'utiliser dans les templates.

                    Par contre, je n'ai pas vraiment trouvé de moyen pour utiliser les URL relatives...

                    Savez-vous comment faut-il faire ?

                    Merci d'avance pour votre aide.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      10 août 2010 à 21:57:35

                      Tu entant quoi par url relative ?
                      Pour ma part j'utilise des fois l'ecriture du type :

                      (lecture/(?P<id>\d+)/$', 'index', {}, 'index.lecture')


                      quand je veux que une url soit utilisable n'importe ou sur le site
                      • Partager sur Facebook
                      • Partager sur Twitter
                        10 août 2010 à 22:08:54

                        Salut,
                        avant j'utilisais PHP (la honte :p ) et c'est probablement ce qui a créé ma confusion.
                        En PHP, c'est organisé par dossier.

                        Avec Django, c'est différent.

                        Donc, si je comprends bien, si je veux écrire un lien court dans un template, je dois lui donner un nom dans le URLconf.

                        J'imagine que c'est préférable ne de pas faire ça dans ce gros projets, n'est-ce pas ?

                        Merci d'avance pour votre aide.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          10 août 2010 à 22:25:51

                          Dans man cas les pages utiliser est :
                          le dossier media , les pages final. ( lecture de news, de video , messages. )

                          Exemple :
                          Accuiel / lecture video
                          liste video / lecture video
                          Recherche / lecture video
                          Tag / lecture video
                          • Partager sur Facebook
                          • Partager sur Twitter
                            11 août 2010 à 3:52:38

                            Hello.

                            Ton code viole la PEP8 : http://www.python.org/dev/peps/pep-0008/
                            TOUS les noms doivent être en anglais. (et c'est valable pour TOUS les langages, coder en français, c'est rendre son code incompréhensible pour 95% de la communauté)
                            Les méthodes doivent être nommées comme_ca, et pas commeCa.

                            De rien
                            • Partager sur Facebook
                            • Partager sur Twitter
                              11 août 2010 à 7:11:59

                              La pep8, soit dit en passant, est violée par pas mal des tutoriels python du site...

                              Donc, c'est plutôt compréhensible que peu de personnes l'appliquent...
                              • Partager sur Facebook
                              • Partager sur Twitter
                                11 août 2010 à 15:06:23

                                Citation : Eiji Okuda

                                La pep8, soit dit en passant, est violée par pas mal des tutoriels python du site...

                                Donc, c'est plutôt compréhensible que peu de personnes l'appliquent...



                                Et c'est peut être le truc que je déteste le plus chez les programmeurs Python, le manque de respect envers les normes... Au final ca va finir plein d'incohérences comme PHP...
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  11 août 2010 à 15:13:41

                                  Salut,
                                  pour les noms de variables avec des traits de soulignement, je vais faire un effort, car Django les utilise déjà.

                                  Cependant, je ne vois pas pourquoi j'écrirais les noms en anglais.
                                  Ça me rajouterais du travail, car je devrais, par exemple, rajouter un label à TOUS les champs d'un formulaire.
                                  Pour le chat, il n'y en a pas beaucoup, mais ça peut vraiment alourdir le code.

                                  Effectivement, il me semble que la pep8 permet de violer une règle lorsqu'elle rend le code moins lisible, donc je vais garder les noms en français.

                                  Merci pour vos commentaires.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    11 août 2010 à 15:45:51

                                    Je vois pas en quoi ca rend le code moins lisible, avec des champs en français, tu te prive de toute l'aide international (90% ?), ça vaut carrément pas le coût, et tout façon, si tu veut localiser ton site, tu sera obliger de mettre des labels, donc autant prendre de bonnes habitudes maintenant..

                                    De plus, Django est en anglais, Python est en anglais, pourquoi irais tu faire un truc en français ? Pour avoir du franglais ?
                                    • Partager sur Facebook
                                    • Partager sur Twitter

                                    <Django> Venez commenter mon code de Mini-Chat

                                    × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                    × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                    • Editeur
                                    • Markdown