diff --git a/.gitignore b/.gitignore index b6e4761..a657fec 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ __pycache__/ *.py[cod] *$py.class - +.idea/ # C extensions *.so @@ -58,7 +58,6 @@ coverage.xml # Django stuff: *.log local_settings.py -db.sqlite3 db.sqlite3-journal # Flask stuff: diff --git a/README.md b/README.md index 0cf4be3..3039fb1 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,36 @@ -# django-practice -Exercices pratiques pour le framework Django. +# Exercices Django + +## Les requêtes + +Pour cet exercice, vous disposez du modèle `Book` et du modèle `Author` définis dans [src/store/models.py](src/store/models.py). + +La base de données contient plusieurs livres et auteurs déjà créés. + +Pour recréer les données de tests de la base de données, vous pouvez exécuter le script [src/store/create_test_data.py](src/store/create_test_data.py). + +Dans cet exercice vous devez : + +### Créer des données +- Créez le livre « Les Misérables » et son auteur associé (Victor Hugo). + - Le livre doit avoir un prix de 4,95€. + - Le livre est rangé dans la catégorie "Aventure". + - Pour le résumé vous pouvez mettre la valeur que vous souhaitez. + - Pour le stock, la bibliothèque dispose de 5 exemplaires. + +### Récupérer des données +- Récupérer tous les livres dont le nombre d'exemplaires en stock est de 0. +- Récupérer tous les livres dont le prix est strictement inférieur à 10€. +- Récupérer tous les livres de Victor Hugo. +- Récupérer le nom de l'auteur du livre « Les Trois Mousquetaires ». +- Récupérer la valeur totale du stock de la bibliothèque (le prix de tous les livres * le nombre en stocks). +- Récupérer le nombre total de livres dans la bibliothèque (le stock de tous les livres). + +### Supprimer des données +- Supprimez tous les livres de Victor Hugo. + +Vous pouvez utiliser le fichier [solution.py](src/store/solution.py) pour écrire les différentes requêtes demandées ci-dessus. + +# Solution + +Vous trouverez le code de la solution dans le fichier [solution.py](src/store/solution.py). + diff --git a/src/db.sqlite3 b/src/db.sqlite3 new file mode 100644 index 0000000..31df268 Binary files /dev/null and b/src/db.sqlite3 differ diff --git a/src/practice/settings.py b/src/practice/settings.py index 486210a..b1d6e77 100644 --- a/src/practice/settings.py +++ b/src/practice/settings.py @@ -37,6 +37,7 @@ 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', + 'store', ] MIDDLEWARE = [ diff --git a/src/store/__init__.py b/src/store/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/store/admin.py b/src/store/admin.py new file mode 100644 index 0000000..8c38f3f --- /dev/null +++ b/src/store/admin.py @@ -0,0 +1,3 @@ +from django.contrib import admin + +# Register your models here. diff --git a/src/store/apps.py b/src/store/apps.py new file mode 100644 index 0000000..4b21863 --- /dev/null +++ b/src/store/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + + +class StoreConfig(AppConfig): + name = 'store' diff --git a/src/store/create_test_data.py b/src/store/create_test_data.py new file mode 100644 index 0000000..09d4105 --- /dev/null +++ b/src/store/create_test_data.py @@ -0,0 +1,51 @@ +import os + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "practice.settings") + +import django + +django.setup() + +from store.models import Author, Book + +authors = [ + {"firstname": "Henri", "lastname": "Beyle", "wikipedia": "https://fr.wikipedia.org/wiki/Stendhal"}, + {"firstname": "Victor", "lastname": "Hugo", "wikipedia": "https://fr.wikipedia.org/wiki/Victor_Hugo"}, + {"firstname": "Alexandre", "lastname": "Dumas", "wikipedia": "https://fr.wikipedia.org/wiki/Alexandre_Dumas"}, + {"firstname": "Isaac", "lastname": "Asimov", "wikipedia": "https://fr.wikipedia.org/wiki/Isaac_Asimov"}, +] + +books = [ + {"title": "Les Trois Mousquetaires", "price": 7.95, + "summary": "Les Trois Mousquetaires est le plus célèbre des romans d'Alexandre Dumas père, initialement publié en feuilleton dans le journal Le Siècle de mars à juillet 1844, puis édité en volume dès 1844 aux éditions Baudry et réédité en 1846 chez J. B. Fellens et L. P. Dufour avec des illustrations de Vivant Beaucé. Il est le premier volet de la trilogie romanesque dite « des mousquetaires », à laquelle il donne son nom, suivi par Vingt Ans après (1845) et Le Vicomte de Bragelonne (1847).", + "author": 3, "category": Book.ADVENTURE, "stock": 12}, + {"title": "Les Robots", "price": 12.99, + "summary": "Les Robots (titre original : I, Robot) est un recueil de neuf nouvelles de science-fiction écrites par Isaac Asimov, publié la première fois par Gnome Press en 1950 et traduit en France en 1967.", + "author": 4, "category": Book.SCIENCE_FICTION, "stock": 0}, + {"title": "Fondation", "price": 14.99, + "summary": "Fondation (titre original : Foundation) est un roman de science-fiction rédigé par Isaac Asimov et composé de cinq nouvelles, dont quatre publiées individuellement entre 1942 et 1944 dans la revue Astoundinng Science-Fiction et à laquelle une cinquième fut ajoutée pour former ce livre publié pour la première fois en 19511. C'est le premier volet du Cycle de Fondation. Bien qu’il constitue aujourd'hui le troisième épisode chronologique de ce cycle, il est le premier à avoir été écrit et peut donc être lu indépendamment de Prélude à Fondation et L'Aube de Fondation.", + "author": 4, "category": Book.SCIENCE_FICTION, "stock": 15}, + {"title": "L'homme qui rit", "price": 12.99, + "summary": "L'Homme qui rit est un roman philosophique de Victor Hugo publié en avril 1869 dont l’action se déroule dans l’Angleterre de la fin du xviie et du début du xviiie siècle. Il est notamment célèbre pour la figure mutilée dans un rire permanent de son héros qui a fortement inspiré le monde littéraire et cinématographique.", + "author": 2, "category": Book.ADVENTURE, "stock": 0}, + {"title": "Notre-Dame de Paris", "price": 8.99, + "summary": "Notre-Dame de Paris (titre complet : Notre-Dame de Paris. 1482) est un roman historique de l'écrivain français Victor Hugo, publié en 1831.", + "author": 2, "category": Book.ADVENTURE, "stock": 24}, + {"title": "Le Rouge et le Noir", "price": 21.95, + "summary": "Le Rouge et le Noir, sous-titré Chronique du xixe siècle, puis Chronique de 1830, est un roman écrit par Stendhal, publié pour la première fois à Paris chez Levasseur le 13 novembre 18301, bien que l'édition originale2 mentionne la date de 1831. C'est son deuxième roman, après Armance.", + "author": 1, "category": Book.ADVENTURE, "stock": 8}, + {"title": "La Chartreuse de Parme", "price": 18.95, + "summary": "La Chartreuse de Parme est un roman publié par Stendhal. Cette œuvre majeure, qui lui valut la célébrité, fut publiée en deux volumes en mars 1839, puis refondue en 1841, soit peu avant la mort de Stendhal, à la suite d'un article fameux de Balzac1 et prenant de fait un tour plus « balzacien » : aujourd’hui, c’est le texte stendhalien d’origine qu’on lit encore.", + "author": 1, "category": Book.ADVENTURE, "stock": 7}, +] + +for author in authors: + Author.objects.get_or_create(**author) + +for book in books: + book_author_id = book.pop("author") + book_instance, created = Book.objects.get_or_create(**book) + author = Author.objects.get(pk=book_author_id) + if author: + book_instance.author = author + book_instance.save() diff --git a/src/store/migrations/0001_initial.py b/src/store/migrations/0001_initial.py new file mode 100644 index 0000000..5bb0a84 --- /dev/null +++ b/src/store/migrations/0001_initial.py @@ -0,0 +1,36 @@ +# Generated by Django 3.1.7 on 2021-04-01 18:40 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Author', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('firstname', models.CharField(max_length=150)), + ('lastname', models.CharField(max_length=150)), + ('wikipedia', models.URLField(blank=True)), + ], + ), + migrations.CreateModel( + name='Book', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('title', models.CharField(max_length=300)), + ('price', models.FloatField(blank=True, null=True)), + ('summary', models.TextField(blank=True)), + ('category', models.CharField(blank=True, choices=[('AV', 'Aventure'), ('TR', 'Thriller'), ('FS', 'Fantastique'), ('RM', 'Romance'), ('HR', 'Horreur'), ('SF', 'Science-fiction')], max_length=25)), + ('stock', models.IntegerField(default=0)), + ('author', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='store.author')), + ], + ), + ] diff --git a/src/store/migrations/__init__.py b/src/store/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/store/models.py b/src/store/models.py new file mode 100644 index 0000000..815d13e --- /dev/null +++ b/src/store/models.py @@ -0,0 +1,38 @@ +from django.db import models + + +class Author(models.Model): + firstname = models.CharField(max_length=150) + lastname = models.CharField(max_length=150) + wikipedia = models.URLField(blank=True) + + def __str__(self): + return f"{self.firstname} {self.lastname}" + + +class Book(models.Model): + ADVENTURE = "AV" + THRILLER = "TR" + FANTASY = "FS" + ROMANCE = "RM" + HORROR = "HR" + SCIENCE_FICTION = "SF" + + GENRES = [ + (ADVENTURE, "Aventure"), + (THRILLER, "Thriller"), + (FANTASY, "Fantastique"), + (ROMANCE, "Romance"), + (HORROR, "Horreur"), + (SCIENCE_FICTION, "Science-fiction"), + ] + + title = models.CharField(max_length=300) + price = models.FloatField(blank=True, null=True) + summary = models.TextField(blank=True) + author = models.ForeignKey(Author, on_delete=models.CASCADE, blank=True, null=True) + category = models.CharField(max_length=25, blank=True, choices=GENRES) + stock = models.IntegerField(default=0) + + def __str__(self): + return self.title diff --git a/src/store/solution.py b/src/store/solution.py new file mode 100644 index 0000000..c47ced5 --- /dev/null +++ b/src/store/solution.py @@ -0,0 +1,65 @@ +# Ne modifiez pas les lignes ci-dessous +import os + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "practice.settings") + +import django + +django.setup() +# Ne modifiez pas les lignes ci-dessus + + +# L'exercice commence ici +from store.models import Author, Book + +# Créer des données +"""- Créez le livre « Les Misérables » et son auteur associé (Victor Hugo). + - Le livre doit avoir un prix de 4,95€. + - Le livre n'a pas de catégorie associée. + - Pour le résumé et le nombre d'exemplaires en stock, vous pouvez mettre les valeurs que vous souhaitez. +""" +author, created = Author.objects.get_or_create(firstname="Victor", + lastname="Hugo", + wikipedia="https://fr.wikipedia.org/wiki/Victor_Hugo") + +Book.objects.get_or_create(title="Les Misérables", + author=author, + price=4.95, + category=Book.ADVENTURE, + summary="Dans ce roman emblématique de la littérature française qui décrit la vie de pauvres gens dans Paris et la France provinciale du xixe siècle, l'auteur s'attache plus particulièrement au destin du bagnard Jean Valjean. C'est un roman historique, social et philosophique dans lequel on retrouve les idéaux du romantisme et ceux de Victor Hugo concernant la nature humaine.", + stock=5) + +# Récupérer des données +# - Récupérer tous les livres dont le nombre d'exemplaires en stock est de 0. +empty_stocks = Book.objects.filter(stock=0) +print(f"Livres à racheter : {[book.title for book in empty_stocks]}.") + +# - Récupérer tous les livres dont le prix est strictement inférieur à 10€. +cheap_books = Book.objects.filter(price__lt=10) +print(f"Les livres dont le prix est inférieur à 10€ sont : {[book.title for book in cheap_books]}.") + +# - Récupérer tous les livres de Victor Hugo. +victor_hugo = Author.objects.get(firstname="Victor", lastname="Hugo") +if victor_hugo: + victor_hugo_books = Book.objects.filter(author=victor_hugo) + print(f"Livres écrits par Victor Hugo : {[book.title for book in victor_hugo_books]}.") + +# - Récupérer le nom de l'auteur du livre « Les Trois Mousquetaires ». +les_trois_mousquetaires = Book.objects.get(title="Les Trois Mousquetaires") +author = les_trois_mousquetaires.author +print(f"Les Trois Mousquetaires a été écrit par {author.firstname} {author.lastname}.") + +# - Récupérer la valeur totale du stock de la bibliothèque (le prix de tous les livres). +all_books = Book.objects.filter(stock__gt=0) +total_price = sum(book.price * book.stock for book in all_books) +print(f"Valeur totale du stock : {round(total_price, 2)}€.") + +# - Récupérer le nombre total de livres dans la bibliothèque (le stock de tous les livres). +all_books = Book.objects.filter(stock__gt=0) +total_books = sum(book.stock for book in all_books) +print(f"Nombre de livres en stock : {total_books}.") + +# Supprimer des données +# - Supprimez tous les livres de Victor Hugo. +victor_hugo_books = Book.objects.filter(author__lastname="Hugo", author__firstname="Victor") +victor_hugo_books.delete() diff --git a/src/store/tests.py b/src/store/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/src/store/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/src/store/views.py b/src/store/views.py new file mode 100644 index 0000000..91ea44a --- /dev/null +++ b/src/store/views.py @@ -0,0 +1,3 @@ +from django.shortcuts import render + +# Create your views here.