IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Django Python Discussion :

débuter avec Django


Sujet :

Django Python

  1. #1
    Membre éclairé Avatar de guiyomh
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 328
    Par défaut débuter avec Django
    bonjour,
    voilà je débute avec Django, j'ai suivi les petits tuto que l'on trouve a gauche et a droite sur le web.
    Mais je me pose un certain nombre de question. J'ai déjà l'expérience de quelque autre Framework (en php) => Zend , Symphony

    Et je retrouve pas tout mes petits !

    J'aurais voulu savoir comment faire :
    • un bootstrap (fichier d'amorçage) permettant d'instancier un objet commun a tout les modules
    • comment faire une conf multi-environnement (dev, prod, test, ...)
    • comment pouvoir déporté une partie de la conf dans les modules (genre la réécriture d'url ...)

  2. #2
    Membre Expert
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Par défaut
    Citation Envoyé par guiyomh Voir le message
    bonjour,
    voilà je débute avec Django, j'ai suivi les petits tuto que l'on trouve a gauche et a droite sur le web.
    Mais je me pose un certain nombre de question. J'ai déjà l'expérience de quelque autre Framework (en php) => Zend , Symphony

    Et je retrouve pas tout mes petits !

    J'aurais voulu savoir comment faire :
    • un bootstrap (fichier d'amorçage) permettant d'instancier un objet commun a tout les modules
    • comment faire une conf multi-environnement (dev, prod, test, ...)
    • comment pouvoir déporté une partie de la conf dans les modules (genre la réécriture d'url ...)
    Pour le point 1; je ne connais pas cette notion de bootstrap qui est peut être spécifique aux framework que tu as utilisés. Essayes de me préciser quel est le but (un exemple) de cette fonctionnalité pour voir si l'équivalent existe dans django.

    Pour le 2; pour ma part, j'utilise un test dans le fichier settings.py qui s'appuie sur l'adresse IP de la machine qui héberge le projet. Si c'est une adresse IP locale, je défini les paramètres locaux et inversement.

    Pour le 3; il n'ya a pas de réécriture d'url dans django (au sens apache du terme), vu que c'est toi même qui défini tes routages dans les fichiers urls.py.

    P.S. Pour espérer avoir la réponse la plus précise possible, il est sans doute préférable de donner un exemple de la problématique à résoudre. Les questions précédentes sont très ouvertes et pas sur que je réponde réellement à celle ci d'ailleurs.

  3. #3
    Membre éclairé Avatar de guiyomh
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 328
    Par défaut
    merci pour la réponse.

    Pour le Point1: généralement, le bootstrap est le point d'entrée. Toute les requette passe par lui, c'est dans ce fichier qu'est instancier le controleur de l'application. (je sais pas si je suis clair).

    C'est dans ce fichier ou cette classe, qu'un certain nombre de test sont réalisés pour déterminer l'environnement "dev", "prod ...,

    voici un exemple avec zend :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    <?php
     
    /**
     * Fichier d'armorçage de l'application
     * 
     * @uses    Zend_Application_Bootstrap_Bootstrap
     * @package Gdd
     * @subpackage Bootstrap
     */
    class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
    {
        protected $_config = null;
        protected $_browser = null;
     
        /**
         * Bootstrap autoloader for application resources
         * 
         * @return Zend_Application_Module_Autoloader
         */
        protected function _initAutoload()
        {
            $autoloader = new Zend_Application_Module_Autoloader(array(
                'namespace' => 'Default',
                'basePath'  => dirname(__FILE__),
            ));
            Zend_Loader_Autoloader::getInstance()->registerNamespace('My_');
            return $autoloader;
        }
     
        /**
         * Bootstrap initialisation de la vue
         *
         * @return Zend_View
         */
        protected function _initView()
        {
            $this->bootstrap('config');
            $config = $this->getResource('config');
            // Initialisation de la vue
            $view = new Zend_View();
            $view->doctype('XHTML1_STRICT');
            $view->headTitle($config->site->title)->setSeparator(' - ');
            $view->headLink()->appendStylesheet('/css/blueprint/print.css','print')
                            ->appendStylesheet('/css/blueprint/screen.css','screen,projection')
                            ->appendStylesheet('/css/blueprint/ie.css','screen,projection','IE')
                            ->appendStylesheet('/css/global.css')
                            ->appendStylesheet('/css/ie6.css','screen,projection','lt IE 7')
                            ->headLink(array('rel'=>'icon','href'=>'/images/favicon.ico'),'PREPREND')
                            ->appendAlternate('/feeds/demandes/','application/rss+xml','Liste des demandes');
     
            $view->headScript()->appendFile('/js/mootools-core.js','text/javascript')
                                ->appendFile('/js/mootools-more.js','text/javascript')
                                ->appendFile('/js/pushup.js','text/javascript');
     
            //Zend_Debug::dump(get_browser($_SERVER['HTTP_USER_AGENT']));
            if($config->site->debug==1 && strtolower($this->_browser->browser) != 'firefox')
            {
                $view->headScript()->appendFile('/js/firebug-lite-compressed.js','text/javascript');
            }
     
            $view->headMeta()->appendHttpEquiv('Content-Type','text/html; charset=utf-8');
     
            $view->env = APPLICATION_ENV;
     
            // Ajout dans le ViewRender
            $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer');
            $viewRenderer->setView($view);
            Zend_Dojo::enableView($view);
            Zend_View_Helper_PaginationControl::setDefaultViewPartial('common/pagination_controle.phtml');
            return $view;
        }
     
        /**
         * Initialise les fichier de traduction de l'application
         */
        protected function _initTranslate()
        {
            $this->bootstrap('view');
            $translate = new Zend_Translate('gettext',APPLICATION_PATH.'/languages/lang_fr.mo','fr');
            $translate->setLocale('fr');
            Zend_Form::setDefaultTranslator($translate);
            Zend_Validate_Abstract::setDefaultTranslator($translate);
            Zend_Registry::set('Zend_Translate',$translate);
        }
     
        /**
         * initialise la configuration de l'application
         *
         * @return Zend_Config_Ini
         */
        protected function _initConfig()
        {
            $configMail = new Zend_Config_Ini(APPLICATION_PATH.'/configs/mail.ini');
            Zend_Registry::set('mail',$configMail);
            $this->_config = new Zend_Config_Ini(APPLICATION_PATH.'/configs/application.ini', APPLICATION_ENV);
            Zend_Registry::set('config', $this->_config);
            Zend_Registry::set('env', APPLICATION_ENV);
            Zend_Registry::set('siteurl',$this->_config->siteurl);
            $this->_browser = get_browser($_SERVER['HTTP_USER_AGENT']);
            return $this->_config;
        }
     
        /**
         * Bootstrap initialisation de la base de donnée
         *
         * @return void
         */
        protected function _initDb(array $options = array())
        {
            $this->bootstrap(array('config','frontcontroller'));
            $config = $this->getResource('config');
            $db = Zend_Db::factory($config->resources->db);
     
            $profiler = new Zend_Db_Profiler_Firebug('All DB Queries');
            $profiler->setEnabled($config->debug);
            $db->setProfiler($profiler);
     
            try
            {
                $db->getConnection();
            }
            catch(Zend_Db_Adapter_Exception $e)
            {
                echo $e->getMessage().' <br /> on '.$e->getFile().' : '.$e->getLine().'<br/><br />';
                die('Problème de connection à la base. Veuillez contacter l\'administrateur : '.$config->mail->webmaster);
            }
     
            Zend_Db_Table_Abstract::setDefaultAdapter($db);
            Zend_Registry::set( 'dbAdapter', $db );
            return $db;
        }
     
        /**
         * initialisation de la navigation
         *
         * @return Zend_Navigation
         */
        protected function _initNavigation()
        {
            $this->bootstrap('view');
            $view = $this->getResource('view');
            $config = new Zend_Config_Xml(APPLICATION_PATH.'/configs/menu.xml', 'nav');
            //echo Zend_Debug::dump($config->toArray());
            $nav = new Zend_Navigation($config);
     
            Zend_Registry::set('nav',$nav);
     
            $view->navigation($nav);
            return $nav;
        }
     
        /**
         * Initialisation de la session
         */
        protected function _initSession()
        {
            $this->bootstrap('view');
            $this->bootstrap('navigation');
            $session = Zend_Session::start();
     
            $auth = Zend_Auth::getInstance();
            if(!isset($session->acl))
            {
                $acl = new My_Acl($auth);
                $session->acl = $acl;
                $frontController = Zend_Controller_Front::getInstance();
                $frontController->registerPlugin(new My_Plugin_Auth($auth,$acl));
            }
            Zend_Registry::set('session',$session);
            if ($auth->hasIdentity()) {
                $TUser = new Default_Model_DbTable_User;
                $identity = $TUser->findByIdentifiant(Zend_Auth::getInstance()->getIdentity());
                Zend_Registry::set('identity',$identity);
                $ressouceType = $identity->findParentRow('Default_Model_DbTable_Role','Role')->ressourceType;
                Zend_Registry::set('ressourceType',$ressouceType);
     
                $nav = $this->getResource('navigation');
                if($ressouceType=="ADMIN")
                {
                    $itemNav = $nav->findByUri('/index/administration');
                    $itemNav->setVisible(true);
                    $itemNav = $nav->findByUri('/');
                    $itemNav->setVisible(true);
                    $itemNav = $nav->findByUri('/demande');
                    $itemNav->setVisible(true);
                }
     
                if($ressouceType=="PROD")
                {
                    $itemNav = $nav->findByUri('/demande');
                    $itemNav->setVisible(true);
                }
     
                $view = $this->getResource('view');
                $view->headLink()->appendAlternate('/feeds/mydemandes/','application/rss+xml','Mes demandes');
                //$view->headLink()->appendAlternate('/feeds/mytodo/','application/rss+xml','Ma Todo List');
            }
        }
     
        /**
         * Initialise le Front Controller
         *
         * @return Zend_Controller_Front
         */
        protected function _initFrontcontroller()
        {
            $this->bootstrap('config');
            $config = $this->getResource('config');
            $this->bootstrap('request');
            $request = $this->getResource('request');
     
            $frontController = Zend_Controller_Front::getInstance();
            //$frontController->throwExceptions(false);
     
            $frontController->setControllerDirectory(APPLICATION_PATH .'/controllers');
     
            $frontController->setRequest($request);
     
            $frontController->setParam('env', APPLICATION_ENV);
            $frontController->setParam('config',$config);
            $frontController->setParam('browser',$this->_browser);
            return $frontController;
        }
     
     
        /**
         * Initialisation de la requete
         *
         * @return Zend_Controller_Request_Http
         */
        protected function _initRequest()
        {
            $request = new Zend_Controller_Request_Http();
            $request->setControllerName('error')->setActionName('error');
            return $request;
        }
     
        /**
         * Execute le Front Controller
         *
         */
        public function run()
        {
            $frontController = Zend_Controller_Front::getInstance();
            try{
                $frontController->dispatch();
     
            }
            catch(Exception $e)
            {
                exit('ERROR : '.$e->getMessage());
            }
        }
     
    }
    c'est un que j'ai fais. Il est appeller ainsi dans le fichier index.php :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    (...)
    /** Zend_Application */
    require_once 'Zend/Application.php';
     
     
    // Create application, bootstrap, and run
    $application = new Zend_Application(
        APPLICATION_ENV, 
        APPLICATION_PATH . '/configs/application.ini'
    );
     
    $application->bootstrap();
    $application->run();
    la méthode bootstrap est toujours appeller , et par défaut elle va executé toute les méthodes __init*** définit dans la classe ci-dessous.

    Je m'en sert pour initialiser la connection à la base de donnée, choisir la bonne conf, mettre en place certain élement récursif à toute les pages HTML comme les feuilles de style, certain meta tag ...

    Après c'est une façon de faire et il faut peux être procédé différement avec django.

    Pour le point 2: ça rejoint un peu le point 1 en faite. S'il existe un bootstrap dans django, je devrais pouvoir lui indiquer le bon fichier de conf. Au risque de parraitre tatillon, j'aime pas trop l'idée de faire des tests dans le fichier de conf. Je préfère le déporté en dehors. (une conf est une conf pas un script )

    Pour le point 3, je verrais plus tard. Mais l'idée que j'avais en tête c'était de faire plein de module indépendants les un des autres qui viennent se plug(er) dans l'application par drag and drop dans le "document root". Sans avoir à le déclarée ailleurs. Du coup les module devrait embarquer une conf setting.py et un fichier Url propre à eux.

    Voilà. Si tu pouvais m'indiquer déjà s'il existe une sorte de " bootstrap " . Après je me demande si c'est bien Django qu'il me faut

  4. #4
    Membre Expert
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Par défaut
    Je commencerais par la fin !
    Citation Envoyé par guiyomh Voir le message
    Voilà. Si tu pouvais m'indiquer déjà s'il existe une sorte de " bootstrap " . Après je me demande si c'est bien Django qu'il me faut
    Je ne sais si c'est django qu'il te faut, mais il est certain que si tu essayes de reproduire certaines habitudes que tu as acquises ailleurs, dans django, tu vas droit dans le mur. Ca serait pareil si je passait à zend en cherchant à reproduire django. Ceci étant dis :

    Le seul fichier que l'on peut considérer comme étant un fichier de configuration est settings.py et ce fichier est un script.

    Ma manière de procéder pour déterminer l'environnement dans lequel tourne le projet est la suivante (ceci dans le fichier settings.py). Mon environnement de dev tourne sous windows, mes serveurs de production sous linux.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    ENVDEV = os.environ.get('OS') == 'Windows_NT'
    if ENVDEV:
        DATABASE_ENGINE = 'mysql'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        DATABASE_NAME = 'xxxxxxxx'          # Or path to database file if using sqlite3.
        DATABASE_USER = 'xxxx'              # Not used with sqlite3.
        DATABASE_PASSWORD = 'xxxxxx'        # Not used with sqlite3.
        DATABASE_HOST = 'localhost'         # Set to empty string for localhost. Not used with sqlite3.
        DATABASE_PORT = ''                  # Set to empty string for default. Not used with sqlite3.
    else:
        DATABASE_ENGINE = 'mysql'           # 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
        DATABASE_NAME = 'xxxxxxxx'          # Or path to database file if using sqlite3.
        DATABASE_USER = 'xxxx'              # Not used with sqlite3.
        DATABASE_PASSWORD = 'xxxxxx'        # Not used with sqlite3.
        DATABASE_HOST = 'localhost'         # Set to empty string for localhost. Not used with sqlite3.
        DATABASE_PORT = ''                  # Set to empty string for default. Not used with sqlite3.
    Si cela te dérange que ce soit dans un seul fichier, tu dois pouvoir faire un import conditionnel (pas testé). Même si pour moi cela me paraît plus simple d'avoir un seul fichier avec quelques tests, vu que la plupart des paramètres seront communs aux deux environnements.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ENVDEV = os.environ.get('OS') == 'Windows_NT'
     
    if ENVDEV:
        import config_dev
    else:
        import config_prod
    config_dev et config_prod étant eux mêmes deux scripts python (.py)


    Pour le point 3, cela rejoins la notion d'application de django, que l'on peut installer (plugger) en une seule ligne et qui sont autonome. (voir settings.py)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    INSTALLED_APPS = (
        'django.contrib.admin',
        'django.contrib.auth',
        ....
    Il suffit que l'application soit accessible, quelle que soit sa localisation, ce qui permets de mutualiser une application sur plusieurs projets, ce qui est le cas de l'ensemble des applications django de base : django.contrib.*

    Je te conseille, avant de te lancer sur un gros projet, de reproduire les fondamentaux dont tu as besoin, au sein d'un petit projet.

  5. #5
    Membre éclairé Avatar de guiyomh
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 328
    Par défaut
    Effectivement, je pense être bien imprégnier. C'est dure de sortir de ses habitudes.

    Je trouve Django super et simple. Mais je sais pas il manque un truc. Mais celà dis le projet est récent et ne peux que progresser.

    sinon j'ai commencer à regarder Pylon, et déjà je vois des truc qui me plaisent un peu mieux
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    map.connect('/{controller}/{action}')
    ils raisonnent en therme de controller et d'action, en terme de fichiers de conf.ini avec des environnement de (prod, dev, middleware ...)

    ça ressemble vachement plus a ce que j'ai l'habitude de faire.
    Je pense que je vais me tourné vers ça.

    Je te remercie pour ton aide.
    Peux être as tu une expérience sur d'autre framework python, que tu pourrais me faire partager ?

  6. #6
    Membre Expert
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Par défaut
    Je ne connais que très peu les autres framework python, j'avais fais au moment de mon choix une petite étude comparative (sommaire).

    Le principal avantage que je vois à django, c'est qu'en déclarant juste les modèles, le framework te construit de manière automatique la console d'administration pour la mise à jour des données (cette console étant tout de même paramétrable).

    Si tu t'arrêtes à une fonctionnalité qui te paraît familière (mvc de pylon par exemple), tu risques aussi de te planter En changeant de framework, tu dois oublier le précédent.

    Le principe des vues existe sous django, mais n'est pas déclaré de la même manière et n'est pas tout à fait un modèle MVC dans le sens habituel du terme.

    As tu suivi le tutorial de django ? http://docs.djangoproject.com/en/dev/intro/tutorial01/

    Il aborde les principales fonctionnalités du framework.

    Sinon, question peut etre bête, mais pourquoi laisser tomber zend si tu le maitrises ?

  7. #7
    Membre éclairé Avatar de guiyomh
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    328
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 328
    Par défaut
    je laisse pas tombé Zend, je l'aime beaucoup.

    mais bon j'ai envie de faire du python. j'ai déjà quelque batch a mon actif en python. J'ai beaucoup aimer les développer et je me suis demander a koi ressemblait un framework Python.

    Voilà. J'en suis au début de mon investigation.
    Tout comme toi j'aime beaucoup le principe de générations d'administration auto.

    je viens de voir ceci aussi : http://werkzeug.pocoo.org/

  8. #8
    Membre Expert
    Avatar de DelphiManiac
    Homme Profil pro
    Homme à tout faire
    Inscrit en
    Mars 2002
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Homme à tout faire
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 147
    Par défaut
    Ici, une liste "comparative" des frameworks, y compris ceux en python :

    http://en.wikipedia.org/wiki/List_of...ion_frameworks

Discussions similaires

  1. débuter avec Visual .NET
    Par akimmm dans le forum MFC
    Réponses: 4
    Dernier message: 28/10/2005, 04h53
  2. [GridBagLayout] Comment débuter avec ce layout
    Par Bighobbit dans le forum Débuter
    Réponses: 12
    Dernier message: 28/09/2005, 17h13
  3. [MFC je crois] Débuter avec visual c++
    Par flzox dans le forum MFC
    Réponses: 6
    Dernier message: 28/06/2005, 18h31
  4. [JAXP] Débuter avec XML et Java
    Par Fleep dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 04/05/2005, 11h27
  5. Débuter avec Java
    Par reptils dans le forum Débuter avec Java
    Réponses: 9
    Dernier message: 11/07/2004, 21h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo