from django.db import models from django.urls import reverse from django.core.validators import MinValueValidator from django.core.exceptions import ValidationError from autoslug import AutoSlugField from website.validators import MaxFileSizeValidator from accounts.models import User from inventory.models import Category, Tag from comments.models import AbstractComment class Suggestion(models.Model): title = models.CharField(verbose_name="titre du jeu", max_length=256, unique=True) slug = AutoSlugField(populate_from="title", unique=True) price = models.DecimalField( max_digits=6, decimal_places=2, verbose_name="prix en euros", validators=[MinValueValidator(0)], ) buy_link = models.URLField(verbose_name="lien vers un site d'achat") 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_precisions = models.CharField( max_length=256, blank=True, verbose_name="précisions sur le nombre de joueur·se·s", help_text="Pour indiquer une éventuelle contrainte (ex. parité) ou information sur le nombre de joueur·se·s", ) duration = models.CharField(max_length=256, 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.SET_NULL, blank=True, null=True, verbose_name="catégorie", help_text="Idée de catégorie dans laquelle ranger ce jeu", ) tags = models.ManyToManyField( Tag, blank=True, verbose_name="tags qui correspondent à ce jeu", help_text="Vous pouvez en sélectionner plusieurs ou aucun (sur ordinateur Ctrl+Clic change l'état de selection d'un tag)", ) description = models.TextField( blank=True, verbose_name="description", help_text="Peut correspondre à celle de l'éditeur et ne doit pas contenir d'avis personnel", ) image = models.ImageField( upload_to="suggestion_img/", blank=True, verbose_name="image", help_text="Image du jeu de moins de 512 Kio à téléverser (par exemple une photo de sa boite)", validators=[MaxFileSizeValidator(512)], ) upvoting_users = models.ManyToManyField( User, blank=True, related_name="upvoted_suggestions", verbose_name="personnes intéressées", ) class Meta: ordering = ["title"] verbose_name = "suggestion de jeu" verbose_name_plural = "suggestions de jeux" def __str__(self): return self.title def clean(self): if not self.nb_player_min or not self.nb_player_max: 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" } ) def get_player_range(self): precisions = "" if self.player_range_precisions: precisions = " ({})".format(self.player_range_precisions) if self.nb_player_min != self.nb_player_max: return "{} à {} joueur·se·s{}".format( self.nb_player_min, self.nb_player_max, precisions ) else: return "{} joueur·se·s{}".format(self.nb_player_min, precisions) def get_absolute_url(self): return reverse("suggestions:suggestion", args=(self.slug,)) class SuggestionComment(AbstractComment): commented_object = models.ForeignKey( Suggestion, on_delete=models.CASCADE, related_name="comments", verbose_name="suggestion", ) class Meta: ordering = ["created_on"] verbose_name = "commentaire sur une suggestion" verbose_name_plural = "commentaires sur des suggestions" def get_modification_url(self): return reverse( "suggestions:modify_suggestion_comment", args=(self.commented_object.slug, self.id), )