import os from django.db import models from django.dispatch import receiver from django.urls import reverse from .fields import ChoiceArrayField class Ingredient(models.Model): nom = models.CharField("Nom", max_length=200) class Meta: ordering = ('nom',) def __str__(self): return self.nom class Unite(models.Model): nom = models.CharField("Unité", max_length=200) def __str__(self): return self.nom class Recette(models.Model): SAISON_CHOICES = ( ('printemps', 'Printemps'), ('été', 'Été'), ('automne', 'Automne'), ('hiver', 'Hiver'), ) nom = models.CharField("Nom", max_length=200) photo = models.ImageField("Photo", upload_to='photos', blank=True) photo_instr = models.ImageField("Photo des instructions", upload_to='photos', blank=True) nb_pers = models.IntegerField(default=4) saison = ChoiceArrayField( models.CharField(max_length=10, choices=SAISON_CHOICES, blank=True), verbose_name="Saison", ) is_veget = models.BooleanField("Mets végétarien", default=False) is_dessert = models.BooleanField("Dessert", default=False) prep = models.TextField("Préparation", blank=True) source = models.CharField("Source", max_length=200, blank=True) ingredients = models.ManyToManyField(Ingredient, through='Composition', blank=True) class Meta: ordering = ('nom',) def __str__(self): return self.nom def get_absolute_url(self): return reverse('recette', args=[self.pk]) class Composition(models.Model): recette = models.ForeignKey(Recette, on_delete=models.CASCADE) ingredient = models.ForeignKey(Ingredient, on_delete=models.PROTECT) quantite = models.DecimalField(max_digits=6, decimal_places=3, null=True, blank=True) unite = models.ForeignKey(Unite, null=True, blank=True, on_delete=models.PROTECT) def __str__(self): return "%s %s %s" % ( self.quantite_formatted or '', self.unite.nom if self.unite else '', self.ingredient.nom ) @property def quantite_formatted(self): if self.quantite is None: return '' return str(self.quantite).rstrip('0').rstrip('.') @receiver(models.signals.post_delete, sender=Recette) def auto_delete_photo_on_delete(sender, instance, **kwargs): """ Delete file from filesystem when corresponding `Recette` object is deleted. """ if instance.photo: if os.path.isfile(instance.photo.path): os.remove(instance.photo.path) @receiver(models.signals.pre_save, sender=Recette) def auto_delete_photo_on_change(sender, instance, **kwargs): """ Delete old file from filesystem when corresponding `Recette` object is updated with new file. """ if not instance.pk: return False try: old_file = Recette.objects.get(pk=instance.pk).photo except Recette.DoesNotExist: return False if old_file and old_file != instance.photo and os.path.isfile(old_file.path): os.remove(old_file.path)