Les modèles - models.py¶
date: | 2012-05-01 17:52 |
---|---|
tags: | django, python |
category: | Django |
author: | Rémy Hubscher |
Le MVT de Django¶
Le découpage d’une application Django se fait en trois parties :
- Le modèle
- La vue
- Le template
Vous avez déjà eu un léger aperçu de ces trois parties dans le TP précédent.
Le modèle¶
Django est basé sur un ORM. On va donc créer des objets Python qui vont être capable de se caller automatiquement à une base de données relationnelle.
Cela va nous permettre de faire tourner notre application sur le SGBD de notre choix :
- SQLite,
- MySQL,
- PostgreSQL,
- Oracle,
- MSSQL,
- etc.
Un modèle Django est donc simplement une classe Python qui hérite de django.db.models.Model.
from django.db import models
class Person(models.Model):
first_name = models.CharField(u'Firstname', max_length=30)
last_name = models.CharField(u'Lastname', max_length=30)
Les champs disponibles¶
Il en existe un certain nombre : https://docs.djangoproject.com/en/dev/ref/models/fields/
Certains que vous allez utiliser très souvent, d’autres moins souvent :
- BooleanField
- CharField
- IntegerField
- DateField
- DateTimeField
- EmailField
- ImageField
- FileField
- IPAdressField
- SlugField
- TextField
- URLField
- etc.
Vous allez même parfois devoir en créer pour vos propres besoins.
Chaque champ peut avoir des arguments spécifiques et une fonction de validation spécifique.
Utilisation d’un ModelField¶
Pour chaque field, il y a des paramètres.
- Le premier, commun à tous, est le label
- Ensuite on utilise des paramètres nommés spécifiques à chaque field.
Quelques paramètres globaux :
- unique : Boolean - Permet de spécifier que la valeur est unique (le champ identifie donc la fiche)
- blank : Boolean - On autorise le champ a être vide
- null : Boolean - Si le champ est vide, on stocke le champ comme Null - À utiliser pour les champs qui ne sont pas des chaines de caractères si vous acceptez qu’ils soient vides.
- choices : Tuple - Permet le choix d’une valeur dans une liste définie, éventuellement avec des groupes de choix.
- default : La valeur par défaut lorsque le champ n’est pas saisie.
- editable : Boolean - Si on le met à False le champ ne sera pas éditable par l’utilisateur
- verbose_name : String - Nom du champ pour les utilisateurs
- help_text : String - En plus du verbose_name permet de définir une explication sur ce que doit contenir le champ.
Il y a d’autres paramètres que vous pouvez trouver dans la documentation.
CharField¶
C’est une zone de texte simple avec une taille maximale, max_length comprise entre 0 et 255.
S’il vous faut plus, utilisez un TextField.
from django.db import models
from django.utils.translation import ugettext_lazy as _
GENDER_CHOICES = (('Mr', _('Mister')),
('Mrs', _('Madam')),
('Miss', _('Miss')))
class Person(models.Model):
gender = models.CharField(_('gender'), max_length=4, choices=GENDER_CHOICES)
first_name = models.CharField(_('firstname'), max_length=30)
last_name = models.CharField(_('lastname'), max_length=30)
def __unicode__(self):
return u'%s %s %s' % (self.gender, self.first_name, self.last_name)
DateField et DateTimeField¶
Ces deux champs sont semblable, l’un contient une date et l’autre la date et l’heure.
Deux paramètres intéressant :
- auto_now : Boolean - Est mise à jour automatiquement dès que l’objet est sauvegardé.
- auto_now_add : Boolean - Est mise à jour automatiquement lors de la création de l’objet.
Lorsque auto_now ou auto_now_add sont sélectionné editable est automatiquement mis à False et blank à True.
ImageField et FileField¶
- upload_to : Le chemin vers lequel enregistrer le fichier dans le MEDIA_ROOT, ce peut aussi être l’adresse d’une fonction (un callable) qui va s’occuper de retourner le nom du fichier.
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.template.defaultfilters import slugify
from django.utils.encoding import smart_str
import os.path
def upload_to_valid_name(prefix_dir):
def get_valid_name(instance, name):
root, ext = os.path.splitext(name)
root = smart_str(slugify(root).replace('-', '_'))
return os.path.join(prefix_dir, '%s.%s' % (root, ext))
return get_valid_name
class Firm(models.Model):
name = models.CharField(_(u'name'), max_length=50,
help_text=_(u"Enter the name of the firm"))
image = models.ImageField(_(u'logo'),
upload_to=upload_to_valid_name('uploads/logo'),
null=True, blank=True)
def __unicode__(self):
return u'%s' % self.name
La méthode __unicode__¶
La méthode __unicode__ permet de définir le nom de l’instance de l’objet.
Elle est utilisé notamment lorsqu’on fait un print de l’objet.
La class Meta¶
Elle permet de définir des informations sur l’objet.
Notamment le verbose_name qui définit le nom de l’objet et le ordering qui définit l’ordre de tri par défault des objets.
from django.db import models
from django.utils.translation import ugettext_lazy as _
GENDER_CHOICES = (('Mr', _('Mister')),
('Mrs', _('Madam')),
('Miss', _('Miss')))
class Person(models.Model):
gender = models.CharField(_('gender'), max_length=4, choices=GENDER_CHOICES)
first_name = models.CharField(_('firstname'), max_length=30)
last_name = models.CharField(_('lastname'), max_length=30)
def __unicode__(self):
return u'%s %s %s' % (self.gender, self.first_name, self.last_name)
class Meta:
verbose_name = _('person')
verbose_name_plural = _('people')
ordering = ['last_name', 'first_name']
Autres méthodes¶
Voici quelques informations intéressante, vous pouvez aussi ajouter les méthodes que vous souhaites à vos objets, pour retourner l’âge à partir de la date de naissance par exemple.
from datetime import date
from django.db import models
from django.utils.translation import ugettext_lazy as _
class Person(models.Model):
name = models.CharField(_('name'), max_length=60,
help_text=_('Enter the person full name'))
dob = models.DateField(_('date of birth'))
def __unicode__(self):
return u'%s' % self.name
def age(self):
today = date.today()
num_years = int((today - self.dob).days / 365.2425)
return num_years
Lors de l’utilisation :
$ python manage.py shell
>>> from person.models import Person
>>> from datetime import date
>>> me = Person(name=u'Rémy Hubscher', dob=date(1987, 2, 21))
>>> print me
Rémy Hubscher
>>> me.age()
25
Conclusion¶
Voici donc un bref aperçu des modèles.
Une fois le modèle fait, il faut le créer dans la base de données
$ python manage.py syncdb
Vous pouvez aussi utiliser django-south pour gérer la modification de vos modèles sans perdre les données qui sont dedans.