Historique de Documentation.PremiersPasAvecDjango

Cacher les modifications mineures - Affichage de la sortie

01/06/2014 13:58 par Pierre - ajout du code source
Lignes 546-548 modifiées:
!!! Moteur de templates
en:
!!! Moteur de templates

Source: Attach:tracker.tar.gz
05/01/2014 20:39 par Pierre -
Lignes 498-499 modifiées:
http://127.0.0.1:8000/ et admirer. Même si django nous dit que l'on a rien fait on a en réalité une interface d'administration fonctionnelle.
en:
http://127.0.0.1:8000/ et admirer. Même si django nous dit que l'on a rien fait, on a en réalité une interface d'administration fonctionnelle.
Ligne 502 modifiée:
Par défaut, l'application de gestions des utilisateurs est enregistrée. Vous pouvez alors rajouter d'autres utilisateurs et gérer les permissions.
en:
Par défaut, seule l'application de gestion des comptes utilisateurs est enregistrée. Vous pouvez dès lors rajouter d'autres utilisateurs et gérer les permissions.
05/01/2014 17:07 par Pierre -
Lignes 516-517 modifiées:
Cependant, on peut trouver illisible la liste. Pour la rendre plus lisible il faut modifier le modèle Item et définir la méthode ''__str__''. C'est la méthode standard en Python qui est appelée pour convertir un objet en chaîne de caractères (avec la fonction ''str()'').
en:
Cependant, on peut trouver illisible la liste. Pour la rendre plus lisible il faut modifier le modèle Item et définir la méthode @@__str__@@. C'est la méthode standard en Python qui est appelée pour convertir un objet en chaîne de caractères (avec la fonction ''str()'').
Ligne 532 modifiée:
''__str__'' doit retourner une chaîne de caractères. Ici, j'utilise la méthode ''format'' pour obtenir des valeurs comme ''Item(2, Regarder FLCL)''. J'ai mis l'id dans la chaîne pour faciliter le debuggage. L'utilisation du shell sera plus agréable (il faut le relancer pour que les modifications de code prennent effet) :
en:
@@__str__@@ doit retourner une chaîne de caractères. Ici, j'utilise la méthode ''format'' pour obtenir des valeurs comme ''Item(2, Regarder FLCL)''. J'ai mis l'id dans la chaîne pour faciliter le debuggage. L'utilisation du shell sera plus agréable (il faut le relancer pour que les modifications de code prennent effet) :
05/01/2014 17:07 par Pierre - fautes--
Lignes 50-51 modifiées:
Maintenant, on peut enfin créer l'environnement virtuel. Dans un shell (pas root), taper la commande suivante :
en:
Maintenant, on peut enfin créer l'environnement virtuel. Dans un shell (pas root), tapez la commande suivante :
Lignes 56-57 modifiées:
Pour utiliser votre environnement virtuel, il faut exécuter la commande @@source envdjango/bin/activate@@. Si tout ce passe le prompt de votre shell doit être préfixé par @@(envdjango)@@.
en:
Pour utiliser votre environnement virtuel, il faut exécuter la commande @@source envdjango/bin/activate@@. Si tout ce passe bien le prompt de votre shell doit être préfixé par @@(envdjango)@@.
Lignes 63-64 modifiées:
Normalement si vous taper la commande @@python3 -c "import django"@@, vous avez le droit à un beau message d'erreur :
en:
Normalement si vous tapez la commande @@python3 -c "import django"@@, vous avez le droit à un beau message d'erreur :
Lignes 108-110 modifiées:
On va commencer par un créer un projet django avec la commande @@django-admin.py startproject lenomduprojet@@. Cette commande crée un répertoire ''lenomduprojet'' dans le répertoire courant.
Il est recommandé de l'exécuter dans un répertoire extérieur à l'environnement virtuel. Notre projet va s'appeler tracker, et l'on exécute la commande :
en:
On va commencer par créer un projet django avec la commande @@django-admin.py startproject lenomduprojet@@. Cette commande crée un répertoire ''lenomduprojet'' dans le répertoire courant.
Il est recommandé de l'exécuter dans un répertoire extérieur à l'environnement virtuel. Notre projet va s'appeler '''tracker''', et l'on exécute la commande :
Ligne 127 modifiée:
Le sous-répertoire ''tracker'' contient les fichiers de paramétrages du projet.
en:
Le sous-répertoire ''tracker'' contient les fichiers de paramétrage du projet.
Ligne 133 modifiée:
** la liste des applications installées (@@INSTALLED_APPS@@). Par défaut il s'agit des applications communes à tout projet django (tout ce qui concerne l'authentification l'interface d'administration et les fichiers statiques).
en:
** la liste des applications installées (@@INSTALLED_APPS@@). Par défaut il s'agit des applications communes à tout projet django (tout ce qui concerne l'authentification, l'interface d'administration et les fichiers statiques).
Lignes 141-143 modifiées:
Le script manage.py permet de lancer les commandes de gestions de notre projet.
On va commencer par créer la base de données. En effet, même si on n'a pas encore définit nos modèles de données, django a besoin d'une base de données pour gérer les utilisateurs.
en:
Le script ''manage.py'' permet de lancer les commandes de gestion de notre projet.
On va commencer par créer la base de données. En effet, même si on n'a pas encore définit nos modèles de données, django a besoin d'une base pour gérer les utilisateurs.
Ligne 145 modifiée:
Cette commande vous demande si vous voulez créer un superutilisateur :
en:
Cette commande vous demande si vous voulez créer un super-utilisateur :
Lignes 169-170 modifiées:
Une fois cette commande exécutée, on peut constater la création d'une base sqlite (fichier db.sqlite3).
en:
Une fois cette commande exécutée, on peut constater la création d'une base sqlite (fichier ''db.sqlite3'').
Lignes 179-180 modifiées:
Cela créer un dossier todolist qui contient les fichiers suivant :
en:
Cela crée un dossier todolist qui contient les fichiers suivant :
Ligne 184 modifiée:
* ''views.py'', ce fichier contient les vues qui produiront du html
en:
* ''views.py'', ce fichier contient les vues qui répondront aux requêtes http
Lignes 210-212 modifiées:
Un ORM, pour Object-Relational Mapping (mapping objet-relationnel)  est une technique de programmation informatique qui crée l'illusion d'une base de données orientée objet à partir d'une base de données relationnelle en définissant des correspondances entre cette base de données et les objets du langage utilisé. On pourrait le désigner par « correspondance entre monde objet et monde relationnel ».
Ça c'est la définition Wikipedia. En clair, cela signifie que l'on écrit pas de SQL, que ce soit pour la définition du schéma ou les requêtes. À la place on écrit des classes Python et on attaque la base avec des méthodes sur les objets.
en:
Un ORM, pour Object-Relational Mapping (mapping objet-relationnel) est une technique de programmation informatique qui crée l'illusion d'une base de données orientée objet à partir d'une base de données relationnelle en définissant des correspondances entre cette base de données et les objets du langage utilisé. On pourrait le désigner par « correspondance entre monde objet et monde relationnel ».
Ça c'est la définition Wikipedia. En clair, cela signifie que l'on n'écrit pas de SQL, que ce soit pour la définition du schéma ou les requêtes. À la place, on écrit des classes Python et on attaque la base avec des méthodes sur les objets.
Ligne 217 modifiée:
* c'est plus lisible que du SQL, surtout quand on n'a pas de jointure à écrire
en:
* c'est plus lisible que du SQL, surtout quand on n'a pas de jointure à écrire à la main
Lignes 248-250 modifiées:
On définit une classe '''Item''' qui hérite de models.Model. Notre application va gérer des listes de tâches à faire.
J'ai donc choisi Item comme nom. Cela correspond grosso modo au nom de la table. Il vaut mieux nommer les classes en CamelCase (convention Python) et au singulier (django utilise le terme au singulier dans l'interface d'administration).
en:
On définit une classe '''Item''' qui hérite de ''models.Model''. Notre application va gérer des listes de tâches à faire.
J'ai donc choisi ''Item'' comme nom. Cela correspond grosso modo au nom de la table. Il vaut mieux nommer les classes en CamelCase (convention Python) et au singulier (django utilise le terme au singulier dans l'interface d'administration).
Ligne 257 modifiée:
En quelque sorte on définit les colonnes comme attributs de la classe. Cela peut surprendre les habitués au langage Python. En fait c'est la classe Model qui fait tout grâce a une jolie metaclasse (si vous ne comprenez pas c'est normal).
en:
En quelque sorte, on définit les colonnes comme attributs de la classe. Cela peut surprendre les habitués au langage Python. En fait c'est la classe Model qui fait tout grâce a une jolie métaclasse (si vous ne comprenez pas c'est normal).
Lignes 267-271 supprimées:
 CommandError: One or more models did not validate:
 todolist.item: "titre": CharFields require a "max_length" attribute that is a positive integer.

Il nous dit l'attribut "titre" de notre modèle Item n'est pas valide car il manque un attribut max_length. C'est la longueur maximale de notre chaîne de caractères. On va donc modifier le modèle :

Lignes 269-275 ajoutées:
CommandError: One or more models did not validate:
todolist.item: "titre": CharFields require a "max_length" attribute that is a positive integer.
@]

Il nous dit que l'attribut "titre" de notre modèle Item n'est pas valide car il manque un attribut ''max_length''. C'est la longueur maximale de notre chaîne de caractères. On va donc modifier le modèle :

[@
Lignes 299-303 modifiées:
On remarquer dans la trace d'exécution que la table todolist_item a été créée. Son nom est dérivé du nom de l'application et de celui du modèle.

On n'a pas définit de colonne contenant une clé primaire. En fait django définit automatiquement une colonne ''id''
si on ne spécifie pas de clé primaire. C'est souvent une bonne idée de garder cette colonne. Ça ne coûte pas grand chose et ça facilite les jointures.
en:
On remarquer dans la trace d'exécution que la table ''todolist_item'' a été créée. Son nom est dérivé du nom de l'application et de celui du modèle.

On n'a pas définit de colonne contenant une clé primaire. En fait django définit automatiquement une colonne ''id'' si on ne spécifie pas de clé primaire. C'est souvent une bonne idée de garder cette colonne. Ça ne coûte pas grand chose et ça facilite certaines utilisations de l'ORM.
Lignes 320-321 modifiées:
Une fois la table créée, on peut lui ajouter du contenu. L'un des points intéressants de Python est son interpréteur interactif qui permet de rapidement tester des morceaux de code. Django fournit une commande qui lance un interpréteur avec la connexion à la base de données initialisée :
en:
Une fois la table créée, on peut lui ajouter du contenu. L'un des points forts de Python est son interpréteur interactif qui permet de rapidement tester des morceaux de code. Django fournit une commande qui lance un interpréteur avec la connexion à la base de données établie :
Lignes 326-327 modifiées:
Une fois le shell lancé, on va commencé par importer le modèle Item :
en:
Une fois le shell lancé, on va commencer par importer le modèle Item :
Ligne 335 modifiée:
Nous allons maintenant voir comment on crée un objet Item et on l'enregistre dans la base.
en:
Nous allons maintenant voir comment on crée un objet Item et l'enregistrer dans la base.
Ligne 346 modifiée:
* On ne passe pas directement par le constructeur de la classe Item mais par l'attribut ''objects'' de celle-ci. Cet attribut est automatiquement rajoutés aux modèles. Il sert à séparer les fonctions d'accès à la base aux méthodes propres aux instances des modèles. On parle de ''Manager''.
en:
* On ne passe pas directement par le constructeur de la classe Item mais par l'attribut ''objects'' de celle-ci. Cet attribut est automatiquement rajouté aux modèles. Il sert à séparer les fonctions d'accès à la base aux méthodes propres aux instances des modèles. On parle de ''Manager''.
Lignes 390-391 modifiées:
On sauvegarde l'objet avec save() :
en:
On sauvegarde l'objet avec ''save()'' :
Lignes 490-492 modifiées:
Je vous encourage à tester l'utilisation de filter, get. Il y a aussi ''exclude()'' pour exclure des éléments.
Elle prend les mêmes arguments que
filter.
en:
Je vous encourage à tester l'utilisation de ''filter'' et ''get''. Il y a aussi ''exclude()'' pour exclure des éléments.
Elle prend les mêmes arguments que ''
filter''.
Ligne 518 modifiée:
todolist/models.py :
en:
''todolist/models.py'' :
05/01/2014 15:54 par Pierre - interface d'admin
Lignes 493-541 ajoutées:

Il est temps de lancer un serveur web. Django fournit un serveur web de développement. Il n'est donc pas nécessaire de configurer un serveur apache pour tester son code.

Pour lancer le serveur, il faut taper la commande @@./manage.py runserver@@. Ensuite il ne reste plus qu'à ouvrir la page
http://127.0.0.1:8000/ et admirer. Même si django nous dit que l'on a rien fait on a en réalité une interface d'administration fonctionnelle.

Ouvrez la page http://127.0.0.1:8000/admin/ et connectez vous avec votre compte super-utilisateur créé avec le premier syncdb.

Par défaut, l'application de gestions des utilisateurs est enregistrée. Vous pouvez alors rajouter d'autres utilisateurs et gérer les permissions.

Pour activer l'édition des items, il faut modifier le fichier ''todolist/admin.py'' :

[@
from django.contrib import admin

from .models import Item

admin.site.register(Item)
@]

On sauvegarde, on actualise la page et sans relancer le serveur et tada on peut éditer des items. Un clic sur item de la liste permet de le modifier et il y a un bouton "add item" à droite pour en rajouter.

Cependant, on peut trouver illisible la liste. Pour la rendre plus lisible il faut modifier le modèle Item et définir la méthode ''__str__''. C'est la méthode standard en Python qui est appelée pour convertir un objet en chaîne de caractères (avec la fonction ''str()'').

todolist/models.py :

[@
from django.db import models

class Item(models.Model):

    titre = models.CharField(max_length=20)
    description = models.TextField()

    def __str__(self):
        return "Item({}, {})".format(self.id, self.titre)
@]

''__str__'' doit retourner une chaîne de caractères. Ici, j'utilise la méthode ''format'' pour obtenir des valeurs comme ''Item(2, Regarder FLCL)''. J'ai mis l'id dans la chaîne pour faciliter le debuggage. L'utilisation du shell sera plus agréable (il faut le relancer pour que les modifications de code prennent effet) :

[@
In [1]: from todolist.models import Item

In [2]: Item.objects.all()
Out[2]: [<Item: Item(1, un titre)>, <Item: Item(2, Regarder FLCL)>]
@]


Voilà vous êtes parés pour assister à la deuxième session de l'atelier ou continuer la suite du tutoriel quand elle sera mise en ligne.
05/01/2014 15:25 par Pierre - filter
Lignes 402-490 ajoutées:
La récupération d'éléments passe aussi par le manager (''objects'').

* On peut récupérer tous les éléments d'une table avec la méthode ''all()'' :

[@
In [12]: Item.objects.all()
Out[12]: [<Item: Item object>, <Item: Item object>]
@]

On obtient un objet similaire à une liste qui est itérable (comprendre utilisable dans une boucle for) :

[@
In [13]: for item in Item.objects.all():
  ...:    print(item.titre)
  ...:   
un titre
Regarder FLCL
@]

On peut constater que l'on récupère automatiquement des objets Item. Django fait le travail de conversion pour nous.

* Récupérer tous les éléments peut être coûteux et souvent on veut travailler avec des éléments qui répondent à certains critères. Pour cela il faut passer par la méthode ''filter()'' du manager. Cette méthode accepte des arguments nommés un peu particulier.

Il est possible de filtrer sur la valeur d'un attribut :

[@
In [14]: Item.objects.filter(titre="un titre")
Out[14]: [<Item: Item object>]
@]

On obtient une liste similaire à celle de la méthode ''all()''

[@
In [16]: item = Item.objects.filter(titre="un titre")[0]

In [17]: item.description
Out[17]: 'une autre description'
@]

On peut donc utiliser accéder aux éléments avec la notation @@[]@@ de Python.

On peut également filtrer suivant certaines propriétés des attributs. Par exemple, on peut vouloir filtrer sur des nombres supérieurs à une valeur. Le filtrage se fait en donnant un argument construit suivant le format ''nomattribut__filtre=valeur''.
Il y a par exemple un filtre ''startswith'' qui permet de filtrer les chaînes de caractères commençant par une sous-chaîne donnée. Dans notre cas cela donne :

[@
In [18]: flcl = Item.objects.filter(titre__startswith="Reg")[0]
In [19]: flcl.description
Out[19]: 'Ceci est un super conseil en cadeau pour les lecteurs de ce tutoriel'
@]

(Pour les amateurs de Python, les slices sont supportés mais pas les index négatifs)

L'objet retourné par ''filter'' n'est pas une liste mais un ''queryset''. Cet objet permet d'enchaîner les filtrages.
Il faut noter que la requête SQL n'est pas exécutée tout de suite mais au moment de l'évaluation (affichage dans un shell, accès a un élément avec @@[]@@, itération dans une boucle for...).

[@
In [20]: queryset = Item.objects.filter(titre__startswith="Reg")

In [21]: type(queryset)
Out[21]: django.db.models.query.QuerySet
@]

Ici aucune requête n'a été exécutée.

Il y a aussi un filtre ''contains'' qui filtre si une chaîne contient une sous-chaîne (''icontains'' pour un filtrage insensible à la casse)

[@
In [22]: queryset.filter(description__contains="super")
Out[22]: [<Item: Item object>]
@]

Dans le cas où on est sûr qu'une requête ne retourne qu'un élément, on peut utiliser la méthode ''get()''. Elle prend les mêmes paramètres que filter et peut être appliquée après un appel à filter.

On peut par exemple l'utiliser pour obtenir l'item dont l'id vaut 1 :

[@
In [23]: item = Item.objects.get(id=1)

In [24]: item.titre
Out[24]: 'un titre'

In [25]: item = Item.objects.filter(description__contains="super").get(titre="Regarder FLCL")

In [26]: item.id
Out[26]: 2
@]

Je vous encourage à tester l'utilisation de filter, get. Il y a aussi ''exclude()'' pour exclure des éléments.
Elle prend les mêmes arguments que filter.
04/01/2014 15:34 par Pierre - utilsation de l'orm : création
Lignes 319-400 ajoutées:
Une fois la table créée, on peut lui ajouter du contenu. L'un des points intéressants de Python est son interpréteur interactif qui permet de rapidement tester des morceaux de code. Django fournit une commande qui lance un interpréteur avec la connexion à la base de données initialisée :

@@./manage.py shell@@

Cette commande utilise IPython, un interpréteur Python amélioré (complétion avec tab, possibilités d'exécutés des commandes shell en les préfixant par @@!@@ et bien d'autres choses) si celui-ci est installé.

Une fois le shell lancé, on va commencé par importer le modèle Item :

[@
In [1]: from todolist.models import Item

@]

(Si IPython n'est pas installé, le prompt est @@>>> @@)

Nous allons maintenant voir comment on crée un objet Item et on l'enregistre dans la base.
Il y a deux manières, soit on lance une commande qui créé et enregistre en une étape, soit on le fait en deux lignes distinctes.

Pour créer et enregistrer en une étape :

[@
In [2]: mon_item = Item.objects.create(titre="un titre", description="une description")
@]

Explications :

* On ne passe pas directement par le constructeur de la classe Item mais par l'attribut ''objects'' de celle-ci. Cet attribut est automatiquement rajoutés aux modèles. Il sert à séparer les fonctions d'accès à la base aux méthodes propres aux instances des modèles. On parle de ''Manager''.
* Chaque Manager a une méthode ''create'' qui permet de créer et sauvegarder un objet.
* La méthode create accepte comme arguments nommés (@@argument=valeur@@) les attributs que l'on a définit dans la classe Item.

Une fois l'objet créé, on peut le manipuler comme n'importe quel objet Python :

* Accès à l'attribut ''titre'' :

[@In [4]: mon_item.titre
Out[4]: 'un titre'
@]

* Accès à l'id (la valeur est fournie par la base de données) :

[@
In [5]: mon_item.id
Out[5]: 1
@]

* Modification de la description :

[@
In [6]: mon_item.description = "une autre description"
@]

À ce moment là, la modification de la description n'a pas été enregistrée en base. Pour cela il faut appeler la méthode ''save()'' :

[@
In [7]: mon_item.save()
@]

Là deuxième méthode passe par le constructeur de la classe Item et l'appel à la méthode ''save()''

[@
In [8]: mon_item = Item(titre="Regarder FLCL", description="Ceci est un super conseil en cadeau pour les lecteurs de ce tutoriel")
@]

À ce moment là l'objet n'est pas enregistré est son id vaut ''None'' (l'équivalent de null en Python) :

[@
In [9]: mon_item.id is None
Out[9]: True
@]

On sauvegarde l'objet avec save() :

[@
In [10]: mon_item.save()
@]

Il est alors enregistré et a un id :

[@
In [11]: mon_item.id
Out[11]: 2
@]
04/01/2014 14:58 par Pierre - correction du formatage des exemples de code
Lignes 52-53 modifiées:
  virtualenv-3.3 envdjango
en:
@@virtualenv-3.3 envdjango@@
Lignes 65-69 modifiées:
  (envdjango)$ python3 -c 'import django'
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  ImportError: No module named 'django'
en:
[@
(envdjango)$ python3 -c 'import django'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
ImportError: No module named 'django'
@]

Lignes 111-112 modifiées:
 django-admin.py startproject tracker
en:
@@django-admin.py startproject tracker@@
Lignes 115-123 modifiées:
 tracker/
 +--- manage.py
 +--- tracker/
 |  +--- wsgi.py
 |  +--- urls.py
 |  +--- settings.py
 |  +--- __init__.py

en:
[@
tracker/
+--- manage.py
+--- tracker/
|  +--- wsgi.py
|  +--- urls.py
|  +--- settings.py
|  +--- __init__.py
@]
Lignes 147-161 modifiées:
 (envdjango)$ python manage.py syncdb
 Creating tables ...
 Creating table django_admin_log
 Creating table auth_permission
 Creating table auth_group_permissions
 Creating table auth_group
 Creating table auth_user_groups
 Creating table auth_user_user_permissions
 Creating table auth_user
 Creating table django_content_type
 Creating table django_session

 You just installed Django's auth system, which means you don't have any superusers defined.
 Would you like to create one now? (yes/no):
en:
[@
(envdjango)$ python manage.py syncdb
Creating tables ...
Creating table django_admin_log
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_groups
Creating table auth_user_user_permissions
Creating table auth_user
Creating table django_content_type
Creating table django_session

You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no):
@]

Lignes 189-201 modifiées:
 # Application definition

 INSTALLED_APPS = (
     'django.contrib.admin',
     'django.contrib.auth',
     'django.contrib.contenttypes',
     'django.contrib.sessions',
     'django.contrib.messages',
     'django.contrib.staticfiles',
     'todolist',
 )

en:
[@
#
Application definition

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'todolist',
)
@]
Lignes 230-233 modifiées:
 class Item(models.Model):
     titre = models.CharField()
     description = models.TextField()
en:
[@
class
Item(models.Model):
    titre = models.CharField()
    description = models.TextField()
@]

Lignes 238-243 modifiées:
 from django.db import models

 class Item(models.Model):
     titre = models.CharField()
     description = models.TextField()
en:
[@
from
django.db import models

class Item(models.Model):
    titre = models.CharField()
    description = models.TextField()
@]

Lignes 264-265 modifiées:
 ./manage.py syncdb
en:
@@./manage.py syncdb@@
Lignes 273-279 modifiées:
 from django.db import models

 class Item(models.Model):

     titre = models.CharField(max_length=20)
     description = models.TextField()
en:
[@
from
django.db import models

class Item(models.Model):

    titre = models.CharField(max_length=20)
    description = models.TextField()
@]

Lignes 288-294 modifiées:
 (envdjango)$ ./manage.py syncdb
 Creating tables ...
 Creating table todolist_item
 Installing custom SQL ...
 Installing indexes ...
 Installed 0 object(s) from 0 fixture(s)
en:
[@
(envdjango)$ ./manage.py syncdb
Creating tables ...
Creating table todolist_item
Installing custom SQL ...
Installing indexes ...
Installed 0 object(s) from 0 fixture(s)
@]

Lignes 304-314 modifiées:
 (envdjango)$ ./manage.py sql todolist
 BEGIN;
 CREATE TABLE "todolist_item" (
     "id" integer NOT NULL PRIMARY KEY,
     "titre" varchar(20) NOT NULL,
     "description" text NOT NULL
 )
 ;

 COMMIT;
en:
[@
(envdjango)$ ./manage.py sql todolist
BEGIN;
CREATE TABLE "todolist_item" (
    "id" integer NOT NULL PRIMARY KEY,
    "titre" varchar(20) NOT NULL,
    "description" text NOT NULL
)
;

COMMIT;
@]
02/01/2014 22:52 par Pierre -
02/01/2014 22:29 par Pierre - lien vers le tuto officiel en français
Lignes 21-24 ajoutées:
* Un lien vers un tutoriel complet et mieux :

https://docs.djangoproject.com/fr/1.6/intro/tutorial01/

Lignes 303-304 ajoutées:

02/01/2014 22:13 par Pierre - définition d'un modèle
Lignes 283-296 ajoutées:

Les curieux peuvent taper la commande @@./manage.py sql todolist@@ pour voir le schéma SQL généré par django :

 (envdjango)$ ./manage.py sql todolist
 BEGIN;
 CREATE TABLE "todolist_item" (
    "id" integer NOT NULL PRIMARY KEY,
    "titre" varchar(20) NOT NULL,
    "description" text NOT NULL
 )
 ;

 COMMIT;

02/01/2014 22:06 par Pierre - définition d'un modèle
Lignes 211-282 modifiées:
!!!! Définitions
en:
!!!! Définition de modèles

Attention, on va écrire du code ! On va écrire non pas une, non pas deux mais trois lignes dans un fichier !

Il faut éditer le fichier @@todolist/models.py@@. On constate qu'il y a déjà un import du module ''models'' de django.
Il faut remercier les développeurs pour nous éviter l'effort de se souvenir où se trouve ce module.

On rajoute les lignes suivantes à la fin du fichier (on peut virer le commentaire qui commence par #):

 class Item(models.Model):
    titre = models.CharField()
    description = models.TextField()

Ce qui donne pour le fichier complet :

 from django.db import models

 class Item(models.Model):
    titre = models.CharField()
    description = models.TextField()

Explication :

On définit une classe '''Item''' qui hérite de models.Model. Notre application va gérer des listes de tâches à faire.
J'ai donc choisi Item comme nom. Cela correspond grosso modo au nom de la table. Il vaut mieux nommer les classes en CamelCase (convention Python) et au singulier (django utilise le terme au singulier dans l'interface d'administration).

Cette classe hérite de la classe ''models.Model'' (classe Model du module models). C'est la classe de base des modèles dans django.

Ensuite on rajoute deux attributs d'une manière un peu particulière. Ces attributs, '''titre''' est '''description'''
correspondent aux colonnes de la table. Le premier, '''titre''', est définit comme un CharField, ce qui correspond à un champ qui a une longueur maximale fixe. Le deuxième, '''description''', est un TextField, c'est-à-dire une chaîne de caractères de taille variable sans longueur maximale (enfin ça dépend sûrement de la base de données).
Dans le vocabulaire django, on parle de Field.

En quelque sorte on définit les colonnes comme attributs de la classe. Cela peut surprendre les habitués au langage Python. En fait c'est la classe Model qui fait tout grâce a une jolie metaclasse (si vous ne comprenez pas c'est normal).
Ce qu'il faut noter, c'est que l'on n'écrit pas de constructeur, la classe Model en définit un dont nous verrons l'utilisation par la suite.

Pour rappel, il faut que les lignes commençant par titre et description soit indentées (de 4 espaces par convention qui vous évitera des soucis lors de vos futurs copier-coller).

Voilà notre premier modèle est presque fini. Il ne reste plus qu'à mettre à jour le schéma de la base de données avec la commande :

 ./manage.py syncdb

Oups, un message d'erreur en rouge apparaît :

 CommandError: One or more models did not validate:
 todolist.item: "titre": CharFields require a "max_length" attribute that is a positive integer.

Il nous dit l'attribut "titre" de notre modèle Item n'est pas valide car il manque un attribut max_length. C'est la longueur maximale de notre chaîne de caractères. On va donc modifier le modèle :

 from django.db import models

 class Item(models.Model):

    titre = models.CharField(max_length=20)
    description = models.TextField()

Ici on a choisi (au pif) une longueur maximale de 20 caractères (on aurait pu aussi bien mettre 250).
On peut constater que les options des colonnes sont données comme arguments nommés des fields.
Chaque Field a des arguments, certains sont optionnels (comme la valeur par défaut) d'autres sont obligatoires (comme max_length pour les CharFields).

Bon, une fois notre petite erreur corrigée, on peut relancer la commande syncdb.

 (envdjango)$ ./manage.py syncdb
 Creating tables ...
 Creating table todolist_item
 Installing custom SQL ...
 Installing indexes ...
 Installed 0 object(s) from 0 fixture(s)

On remarquer dans la trace d'exécution que la table todolist_item a été créée. Son nom est dérivé du nom de l'application et de celui du modèle.

On n'a pas définit de colonne contenant une clé primaire. En fait django définit automatiquement une colonne ''id''
si on ne spécifie pas de clé primaire. C'est souvent une bonne idée de garder cette colonne. Ça ne coûte pas grand chose et ça facilite les jointures.
02/01/2014 21:32 par Pierre - orm
Lignes 86-87 modifiées:
Aucune idée, mais ça doit être comme sous Linux.
en:
Aucune idée, mais ça doit être comme sous Linux. Normalement il y a déjà un interpréteur Python d'installé (2 ou 3). pip et virtualenv doivent s'installer facilement.
Ligne 155 modifiée:
Répondez oui (yes) et répondeaz aux questions posées. Le super utilisateur est un utilisateur
en:
Répondez oui (yes) et répondez aux questions posées. Le super utilisateur est un utilisateur
Lignes 194-209 ajoutées:


!!!! ORM

Django c'est cool en autre parce qu'il fournit un ORM qui s'intègre très bien dans le framework (ou le contraire).

Un ORM, pour Object-Relational Mapping (mapping objet-relationnel)  est une technique de programmation informatique qui crée l'illusion d'une base de données orientée objet à partir d'une base de données relationnelle en définissant des correspondances entre cette base de données et les objets du langage utilisé. On pourrait le désigner par « correspondance entre monde objet et monde relationnel ».
Ça c'est la définition Wikipedia. En clair, cela signifie que l'on écrit pas de SQL, que ce soit pour la définition du schéma ou les requêtes. À la place on écrit des classes Python et on attaque la base avec des méthodes sur les objets.

Ça a plusieurs avantages :

* le même code est compatible avec toutes les bases de données supportées par Django (postgres, sqlite, oracle) et même MySQL
* ça échappe automatiquement les requêtes SQL &#8594; pas d'injections SQL
* c'est plus lisible que du SQL, surtout quand on n'a pas de jointure à écrire
* on n'a pas à écrire de code pour convertir les données

29/12/2013 16:03 par Pierre - éditeur
Lignes 91-96 ajoutées:

!! Éditeur de texte

Bien entendu vous aurez besoin d'un éditeur de texte. Il n'est pas nécessaire de sortir l'artillerie lourde (eclipse/pydev, c'est plus lourd qu'un maillet de Kaori). Un éditeur avec de la coloration syntaxique pour python, html, css et javascript fera l'affaire. Vim est parfait.

Il est important de configurer son éditeur pour qu'il indente avec 4 espaces (à mort les tabulations).
29/12/2013 15:51 par Pierre - création de l'application
Ligne 117 modifiée:
* ''__init__.py'' : ce fichier vide permet de transformer le dossier tracker en un paquetage python
en:
* ''__init__.py'' : ce fichier vide permet de transformer le dossier tracker en un package python
Lignes 157-158 supprimées:

Lignes 159-185 ajoutées:

Une fois le projet créé, on peut commencer à coder sa première application. Dans django, un projet est composé de plusieurs applications. Celles-ci peuvent être fournie par django, des tierces-parties ou par vous même. Une application regroupe un ensemble cohérent de modèles et de vues. Pour notre projet nous allons créer une seule application, ''todolist'' qui contiendra l'ensemble du code. Mais si nous voulions rajouter un module de commentaire ou un blog, cela se ferait par l'ajout d'applications séparées.
 
Pour créer l'application, il faut lancer la commande @@./manage.py startapp todolist@@.

Cela créer un dossier todolist qui contient les fichiers suivant :

* ''__init__.py'', ce fichier vide dit que todolist est un package python
* ''models.py'', ce fichier sert à définir les modèles de données
* ''admin.py'', ce fichier sert à définir quels modèles sont exposés dans l'interface d'administration
* ''views.py'', ce fichier contient les vues qui produiront du html
* ''tests.py'', ce fichier contient les tests unitaires et fonctionnels que l'on peut (et doit) écrire

Il faut encore enregistrer notre application. Pour cela il faut éditer le fichier ''tracker/settings.py'' et rajouter  @@'todolist'@@ à la liste des applications installées (après les applications django) :

 # Application definition

 INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'todolist',
 )

29/12/2013 15:25 par Pierre - manage.py
Lignes 125-156 ajoutées:

!!! Premières utilisations de manage.py

Le script manage.py permet de lancer les commandes de gestions de notre projet.
On va commencer par créer la base de données. En effet, même si on n'a pas encore définit nos modèles de données, django a besoin d'une base de données pour gérer les utilisateurs.

La création de la base se fait avec la commande @@python manage.py syncdb@@.
Cette commande vous demande si vous voulez créer un superutilisateur :
 
 (envdjango)$ python manage.py syncdb
 Creating tables ...
 Creating table django_admin_log
 Creating table auth_permission
 Creating table auth_group_permissions
 Creating table auth_group
 Creating table auth_user_groups
 Creating table auth_user_user_permissions
 Creating table auth_user
 Creating table django_content_type
 Creating table django_session

 You just installed Django's auth system, which means you don't have any superusers defined.
 Would you like to create one now? (yes/no):

Répondez oui (yes) et répondeaz aux questions posées. Le super utilisateur est un utilisateur
qui au niveau de l'interface d'administration possède tous les droits.
Dans le cadre d'un environnement de développement, l'adresse mail n'a pas besoin d'être valide
et vous pouvez modifier à tout moment le mot de passe avec la commande @@python manage.py changepassword@@.

Une fois cette commande exécutée, on peut constater la création d'une base sqlite (fichier db.sqlite3).

Pour gagner du temps, vous pouvez rendre le fichier manage.py exécutable (@@chmod +x manage.py@@). Vous n'aurez plus qu'à taper @@./manage.py nomdelacommande@@.
28/12/2013 20:05 par Pierre -
Lignes 101-110 modifiées:
On obtient un répertoire qui contient un fichier ''manage.py'' et un répertoire ''tracker''.
en:
On obtient un répertoire qui contient un fichier ''manage.py'' et un répertoire ''tracker'' :

 tracker/
 +--- manage
.py
 +--- tracker/
 |  +--- wsgi.py
 |  +--- urls.py
 |  +--- settings.py
 |  +--- __init__.py

28/12/2013 18:55 par Pierre - création de projet
Lignes 93-117 ajoutées:

Une fois l'environnement près, on peut commencer à coder.

On va commencer par un créer un projet django avec la commande @@django-admin.py startproject lenomduprojet@@. Cette commande crée un répertoire ''lenomduprojet'' dans le répertoire courant.
Il est recommandé de l'exécuter dans un répertoire extérieur à l'environnement virtuel. Notre projet va s'appeler tracker, et l'on exécute la commande :

 django-admin.py startproject tracker

On obtient un répertoire qui contient un fichier ''manage.py'' et un répertoire ''tracker''.

Le fichier ''manage.py est'' un script qui permet de lancer les commandes django relatives à notre projet (création de la base de données, lancement du serveur de développement, etc.).

Le sous-répertoire ''tracker'' contient les fichiers de paramétrages du projet.
Il contient 4 fichiers :

* ''__init__.py'' : ce fichier vide permet de transformer le dossier tracker en un paquetage python
* ''settings.py'' : ce fichier contient les paramètres du projets :

** la liste des applications installées (@@INSTALLED_APPS@@). Par défaut il s'agit des applications communes à tout projet django (tout ce qui concerne l'authentification l'interface d'administration et les fichiers statiques).
** les accès à la base de données (par défaut une base sqlite) (@@DATABASES@@)
** D'autres paramètres comme la langue par défaut (@@LANGUAGE_CODE@@)
* ''urls.py'' : ce fichier permet de décrire sous forme d'expressions régulières à quelles fonctions python sont associées les urls.
* ''wsgi.py'' : ce fichier sert au déploiement sous apache (avec mod_wsgi) ou sous nginx+uwsgi ou nginx+gunicorn et d'autres serveurs frontaux.

28/12/2013 17:50 par Pierre - installation sous windows /o\
Lignes 73-82 modifiées:
C'est un peu pareil que sous Linux mais la console est pourrie.
en:
C'est un peu pareil que sous Linux mais la console est pourrie. Du coup, on oublie l'histoire d'environnement virtuel et on installe que python et django.

!!!! Python

Il faut récupérer l'installateur sur [[http://python.org/download/|le site officiel]].
Lors de l'installation, il est recommandé d'activer le rajout de python.exe dans le path.

!!!! Django

Il faut ouvrir une console (cmd.exe). Puis il faut taper quelque chose comme @@C:\\Python3.3\Scripts\easy_install.exe django@@. Une fois installer, la commande @@python3.exe C:\\Python3.3\Scripts\django-admin.py@@ doit afficher un beau message d'aide
.
28/12/2013 17:19 par Pierre - installation sous linux
Lignes 23-24 modifiées:

Il y a plusieurs manières
en:
!!! Sous Linux et sûrement sous les BSD

Il y a plusieurs manières d'installer Django.
On peut l'installer via les paquets, en global, ou dans un environnement virtuel.

Un environnement virtuel, c'est un environnement python local indépendant du système.
On peut travailler avec plusieurs environnements sur une même machine. Ça sert à tester une nouvelle version d'une bibliothèque sans casser son système et c'est facile à reproduire sur une autre machine.
Le soucis c'est que c'est indépendant du gestionnaire de paquets et il faut faire les mises à jour à la main (ça peut être un avantage quand on a pas encore testé la compatibilité avec une nouvelle version de django).

!!!! Python 3

Il faut commencer par installer Python 3, là le plus simple c'est de passer par votre gestionnaire de paquets. @@apt-get install python3-all@@ sous Debian.

Pour tester si python 3 est installé : la commande @@python3@@ dans un shell doit lancer un shell python.

!!!! pip et virtualenv

Ensuite on installe pip, qui est un gestionnaire de paquets pour python. Sous debian il faut installer le paquet @@python3-pip@@. Sinon, l'installation manuelle est détaillée sur [[http://www.pip-installer.org/en/latest/installing.html|le site officiel]].

Ensuite on installe virtualenvwrapper. En root, il faut lancer la commande @@pip3 install virtualenvwrapper@@ (c'est aussi possible d'installer en local, pip3 --help vous en dira plus).

!!!! Création de l'environnement virtuel

Maintenant, on peut enfin créer l'environnement virtuel. Dans un shell (pas root), taper la commande suivante :

  virtualenv-3.3 envdjango

Cela crée un répertoire envdjango qui contient des répertoires bin/, include/ et lib/ avec une copie de python3 dedans. C'est dans ce répertoire que sera installé django.

Pour utiliser votre environnement virtuel, il faut exécuter la commande @@source envdjango/bin/activate@@. Si tout ce passe le prompt de votre shell doit être préfixé par @@(envdjango)@@.

Pour quitter l'environnement virtuel, il suffit d'exécuter la commande @@deactivate@@.


!!!! Installation de django

Normalement si vous taper la commande @@python3 -c "import django"@@, vous avez le droit à un beau message d'erreur :

  (envdjango)$ python3 -c 'import django'
  Traceback (most recent call last):
    File "<string>", line 1, in <module>
  ImportError: No module named 'django'

C'est normal, on a pas installé django, et c'est super simple : @@pip install django@@.
Et tant que l'on y est, on va installé ipython (un shell python plus agréable à utilisé) : @@pip install ipython@@.

Si django est bien installé, la commande @@python3 -c "import django"@@ ne doit pas renvoyer de message d'erreur et la commande @@django-admin.py@@ doit afficher un beau message d'aide.

!!! Sous Windows

C'est un peu pareil que sous Linux mais la console est pourrie.

!!! Sous MacOS

Aucune idée, mais ça doit être comme sous Linux.

!!! Sous Hurd ou un autre truc exotique

Commencez par avoir du réseau qui marche et un clavier fonctionnel…
28/12/2013 16:26 par Pierre - Intro
Lignes 5-20 ajoutées:
Cet article est un petit tutoriel sur Django. Il reprend le contenu de l'atelier du 17 décembre 2013.
Il ne vise en aucun cas à être complet, il sert simplement de rattrapage pour ceux ou celles qui ont raté la première session et veulent participer à la deuxième.

* Mais au fait, c'est quoi Django ?

C'est un framework web écrit en Python. Ça sert donc à écrire des applications web en Python.
C'est un framework libre (sinon il n'aurait pas sa place sur ce site) et il a l'avantage d'être assez simple à aborder et très complet.

* Python 2 ou Python 3 ?

Les deux \o/ Django 1.6 est compatible avec Python 2.6, 2.7 et 3.3. Pour ce tutoriel, on va partir avec Python 3.3 et Django 1.6.

* Et qu'est ce que l'on va faire ?

Une application presque utile ! Ce sera une simple todolist.

Lignes 22-24 ajoutées:


Il y a plusieurs manières
28/12/2013 16:11 par Pierre - Structure du tutoriel premiers pas sous django
Lignes 1-21 ajoutées:
(:title Premiers pas avec Django:)

!! Introduction

!! Installation

!! Création d'un projet

!! Création d'une application

!!! Le modèle de données

!!!! Définitions

!!!! Utilisation

!!! Interface d'administration

!!! Une première vue

!!! Moteur de templates

© 2006-14 Association Actux - Documentation sous licence GFDL - Conception & design: Imaginair.net - Logo: Zazo0o - Propulsé par PmWiki