from django.db import models from django.urls import reverse from django.core.exceptions import ValidationError from autoslug import AutoSlugField from website.validators import MaxFileSizeValidator from comments.models import AbstractComment from loans.models import AbstractLoan class Category(models.Model): name = models.CharField(max_length=256, verbose_name="nom", unique=True) slug = AutoSlugField(populate_from="name", unique=True) class Meta: ordering = ["name"] verbose_name = "catégorie" def __str__(self): return self.name def get_absolute_url(self): return reverse("inventory:category", args=(self.slug,)) class Tag(models.Model): name = models.CharField(max_length=256, verbose_name="nom", unique=True) slug = AutoSlugField(populate_from="name", unique=True) class Meta: ordering = ["name"] def __str__(self): return self.name def get_absolute_url(self): return reverse("inventory:tag", args=(self.slug,)) class Game(models.Model): title = models.CharField(verbose_name="titre du jeu", max_length=256, unique=True) slug = AutoSlugField(populate_from="title", unique=True) nb_player_min = models.PositiveSmallIntegerField( verbose_name="nombre de joueur·se·s minimum" ) nb_player_max = models.PositiveSmallIntegerField( verbose_name="nombre de joueur·se·s maximum" ) player_range = models.CharField( max_length=256, blank=True, help_text="Affichage personnalisé pour le nombre de joueur·se·s", verbose_name="nombre de joueur·se·s", ) duration_min = models.PositiveSmallIntegerField( verbose_name="durée de partie minimale", help_text="En minutes, telle qu'indiquée par l'éditeur", ) duration_max = models.PositiveSmallIntegerField( verbose_name="durée de partie maximale", help_text="En minutes, telle qu'indiquée par l'éditeur, identique à la durée minimale si laissée vide", blank=True, ) duration = models.CharField( max_length=256, blank=True, help_text="Affichage personnalisé pour la durée de la partie", verbose_name="durée de partie", ) game_designer = models.CharField( max_length=256, blank=True, verbose_name="game designer" ) illustrator = models.CharField( max_length=256, blank=True, verbose_name="illustrateur·trice" ) editor = models.CharField(max_length=256, blank=True, verbose_name="éditeur") category = models.ForeignKey( Category, on_delete=models.RESTRICT, verbose_name="catégorie" ) tags = models.ManyToManyField(Tag, blank=True, verbose_name="tags") description = models.TextField(blank=True, verbose_name="description") image = models.ImageField( upload_to="game_img/", blank=True, verbose_name="image", help_text="L'image doit peser 512 Kio au maximum", validators=[MaxFileSizeValidator(512)], ) missing_elements = models.TextField(blank=True, verbose_name="pièces manquantes") class Meta: ordering = ["title"] verbose_name = "jeu" verbose_name_plural = "jeux" def __str__(self): return self.title def clean(self): if not self.nb_player_min or not self.nb_player_max or not self.duration_min: return if self.nb_player_min > self.nb_player_max: raise ValidationError( { "nb_player_max": "Le nombre de joueur·se·s maximum doit être supérieur au nombre de joueur·se·s minimum" } ) if self.duration_max is None: self.duration_max = self.duration_min if self.duration_min > self.duration_max: raise ValidationError( { "duration_max": "La durée maximale doit être supérieure à la durée minimale" } ) def get_player_range(self): if self.player_range: return self.player_range elif self.nb_player_min != self.nb_player_max: return "{} à {} joueur·se·s".format(self.nb_player_min, self.nb_player_max) else: return "{} joueur·se·s".format(self.nb_player_min) def get_duration_range(self): if self.duration: return self.duration elif self.duration_min != self.duration_max: return "{} à {} min".format(self.duration_min, self.duration_max) else: return "{} min".format(self.duration_min) def get_absolute_url(self): return reverse("inventory:game", args=(self.slug,)) class GameComment(AbstractComment): commented_object = models.ForeignKey( Game, on_delete=models.CASCADE, related_name="comments", verbose_name="jeu" ) class Meta: ordering = ["created_on"] verbose_name = "commentaire sur un jeu" verbose_name_plural = "commentaires sur des jeux" def get_modification_url(self): return reverse( "inventory:modify_game_comment", args=(self.commented_object.slug, self.id) ) class GameLoan(AbstractLoan): lent_object = models.ForeignKey( Game, on_delete=models.CASCADE, verbose_name="jeu emprunté" )