| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 | from enum import Enumfrom django.core.validators import MaxValueValidator, MinValueValidatorfrom django.db import modelsfrom django.urls import reversefrom django_extensions.db.fields import AutoSlugFieldfrom emus.utils import ChoiceEnumdef get_screenshot_upload_path(instance, filename):    return f"{instance.game_system.retropie_slug}/screenshots/{filename}"def get_marquee_upload_path(instance, filename):    return f"{instance.game_system.retropie_slug}/marquee/{filename}"def get_video_upload_path(instance, filename):    return f"{instance.game_system.retropie_slug}/videos/{filename}"def get_rom_upload_path(instance, filename):    return f"{instance.game_system.retropie_slug}/{filename}"class Region(Enum):    USA = "US"    EUROPE = "EU"    JAPAN = "JP"class BaseModel(models.Model):    """A base model for providing name and slugged fields for organizational models"""    name = models.CharField(max_length=255)    slug = AutoSlugField(populate_from="name")    class Meta:        abstract = True    def slugify_function(self, content):        return content.replace("_", "-").replace(" ", "-").lower()    def __str__(self):        return self.nameclass Genre(BaseModel):    ...class Publisher(BaseModel):    ...class Developer(BaseModel):    ...class GameSystem(BaseModel):    retropie_slug = models.CharField(        blank=True,        null=True,        max_length=50,    )    def get_absolute_url(self):        return reverse("games:game_system_detail", args=[self.slug])class Game(BaseModel):    class Region(ChoiceEnum):        US = "USA"        EU = "Europe"        JP = "Japan"        X = "Unknown"    game_system = models.ForeignKey(        GameSystem,        on_delete=models.SET_NULL,        null=True,    )    release_date = models.DateTimeField(        blank=True,        null=True,    )    developer = models.ForeignKey(        Developer,        on_delete=models.SET_NULL,        blank=True,        null=True,    )    publisher = models.ForeignKey(        Publisher,        on_delete=models.SET_NULL,        blank=True,        null=True,    )    genre = models.ManyToManyField(        Genre,    )    players = models.SmallIntegerField(        default=1,    )    kid_game = models.BooleanField(        default=False,    )    description = models.TextField(        blank=True,        null=True,    )    rating = models.FloatField(        blank=True,        null=True,        validators=[MaxValueValidator(1), MinValueValidator(0)],    )    video = models.FileField(        blank=True,        null=True,        upload_to=get_video_upload_path,    )    marquee = models.ImageField(        blank=True,        null=True,        upload_to=get_marquee_upload_path,    )    screenshot = models.ImageField(        blank=True,        null=True,        upload_to=get_screenshot_upload_path,    )    rom_file = models.FileField(        blank=True,        null=True,        upload_to=get_rom_upload_path,    )    hack = models.BooleanField(        default=False,    )    hack_version = models.CharField(        max_length=255,        blank=True,        null=True,    )    english_patched = models.BooleanField(        default=False,    )    english_patched_version = models.CharField(        max_length=50,        blank=True,        null=True,    )    undub = models.BooleanField(        default=False,    )    featured = models.BooleanField(        default=False,    )    region = models.CharField(        max_length=2,        choices=Region.choices(),        blank=True,        null=True,    )    def __str__(self):        return f"{self.name} for {self.game_system}"    def get_absolute_url(self):        return reverse("games:game_detail", args=[self.slug])
 |