minimal/django-orm
Environnement virtuel Python3, installation de Django
$ python3 -m venv venv
$ source venv/bin/activate
$ pip install django
Création d’un projet Django django_orm
$ django-admin startproject django_orm
$ cd django_orm
Création d’une ‘application’ foods dans le projet django_orm
$ python manage.py startapp foods
$ cat django_orm/settings.py
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'foods', # <<< ajouter
]
...
Édition des modèles de données
$ cat foods/models.py
from django.db import models
class Nutrient(models.Model):
name = models.CharField('nom', max_length=100)
def __str__(self):
return self.name
class Grp(models.Model):
code = models.CharField(primary_key=True, default='', max_length=100)
name = models.CharField('nom', max_length=100)
father_grp = models.ForeignKey('Grp', null=True, on_delete=models.CASCADE)
def __str__(self):
return self.name
class Food(models.Model):
code = models.CharField(primary_key=True, default='', max_length=100)
name = models.CharField('nom', max_length=100)
grp = models.ForeignKey(Grp, null=True, on_delete=models.CASCADE)
ssgrp = models.ForeignKey(Grp, null=True, on_delete=models.CASCADE, related_name='ssgrp')
ssssgrp = models.ForeignKey(Grp, null=True, on_delete=models.CASCADE, related_name='ssssgrp')
def __str__(self):
return "{}, {}".format(self.name, self.grp)
class NutData(models.Model):
food = models.ForeignKey(Food, on_delete=models.CASCADE)
nutrient = models.ForeignKey(Nutrient, on_delete=models.CASCADE)
value = models.CharField('valeur', max_length=100)
def __str__(self):
return "{}, {}, {}".format(self.food.name, self.nutrient.name, self.value)
Création et application des migrations initiales
$ python manage.py makemigrations
$ python manage.py migrate
$ sqlite3 db.sqlite3
> .schema
...
CREATE TABLE IF NOT EXISTS "foods_food" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(100) NOT NULL, "pict" varchar(300) NULL);
CREATE TABLE IF NOT EXISTS "foods_nutrient" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "name" varchar(100) NOT NULL);
CREATE TABLE IF NOT EXISTS "foods_nutdata" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "value" varchar(100) NOT NULL, "food_id" varchar(100) NOT NULL REFERENCES "foods_food" ("code") DEFERRABLE INITIALLY DEFERRED, "nutrient_id" integer NOT NULL REFERENCES "foods_nutrient" ("id") DEFERRABLE INITIALLY DEFERRED);
...
Interface d’administration
$ cat foods/admin.py
from foods.models import Food, Grp, Nutrient, NutData
from django.contrib import admin
admin.site.register(Food, admin.ModelAdmin)
admin.site.register(Grp, admin.ModelAdmin)
admin.site.register(Nutrient, admin.ModelAdmin)
admin.site.register(NutData, admin.ModelAdmin)
$ python manage.py createsuperuser
...
$ python manage.py runserver
Ouvrir l’url http://localhost:8000/admin
Interaction avec un shell
$ python manage.py shell
>>> from foods.models import Nutrient, Grp
>>> protein = Nutrient(name="Protéines")
>>> protein
Protéines
>>> protein.save()
>>> Nutrient.objects.count()
1
Querysets
Voir: Référence de l’API QuerySet
Tous les aliments dont le nom commence par “Sa” :
list(Food.objects.filter(name__startswith="Sa"))
Tous les aliments dont le nom commence par “Sa” et qui appartiennent au sous-groupe dont le nom est “salades composées et crudités”
list(Food.objects.filter(name__startswith="Sa").filter(ssgrp__name="salades composées et crudités"))
Intégration dans un script
Affiche tous les aliments de la base de données, avec pour chaque aliment la liste de leurs portions
$ cat food_listing.py
import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "django_orm.settings")
django.setup()
# don't import business models before doing `django.setup()`
from foods.models import Food, NutData
for food in Food.objects.all():
print(food.name)
for nut_data in NutData.objects.filter(food=food):
print(">> {}, {}, {}".format(nut_data.food.name, nut_data.nutrient.name, nut_data.value))
