from django.db import models from django.db.models import Q from colorfield.fields import ColorField class Author(models.Model): first_name = models.CharField( verbose_name="First name", help_text="First name of the author of a drink", ) last_name = models.CharField( verbose_name="Last name", help_text="Last name of the author of a drink", ) @property def name(self) -> str: return f"{self.first_name} {self.last_name}" @property def color(self) -> str: value = ord(self.first_name[0].upper()) + ord(self.last_name[0].upper()) return value old_min = ord('A') + ord('A') old_max = ord('Z') + ord('Z') new_min = 0 new_max = 360 return int((value - old_min) / (old_max - old_min) * (new_max - new_min) + new_min) @property def initials(self) -> str: return f"{self.first_name[0].upper()}.{self.last_name[0].upper()}." def __str__(self): return self.initials class Drink(models.Model): name = models.CharField( verbose_name="Name", help_text="Name of the drink, for displaying in overview", ) description = models.TextField( verbose_name="Description", help_text="Free text field that will be shown to the users", blank=True, ) picture = models.ImageField( verbose_name="Picture", help_text="A picture for the overview", blank=True, ) author = models.ForeignKey( verbose_name="Author", help_text="Author of the drink", to=Author, on_delete=models.CASCADE, blank=True, null=True, ) def __str__(self): return self.name class Bottle(models.Model): name = models.CharField( verbose_name="Bottle", help_text="Name of the type bottle. e.g. Coca Cola, *Specific Whiskey*", ) description = models.TextField( verbose_name="Description", help_text="Free text field that will be shown to the users", blank=True, ) picture = models.ImageField( verbose_name="Picture", help_text="A picture for the overview", blank=True, ) color = ColorField( verbose_name="Color", help_text="Color of the drink, used in the UI", image_field="picture", # Auto-populate the color, calculated from the top-left pixel blank=True, ) def __str__(self): return self.name class Unit(models.Model): abbreviation = models.CharField( verbose_name="Abbreviation", help_text="E.g: ml.", ) name = models.CharField( verbose_name="Name", help_text="E.g: ml.", blank=True, ) pump_time = models.FloatField( verbose_name="Pump time", help_text="Amount of time to run the pump for to dispence 1 of these units", blank=True, ) valve_time = models.FloatField( verbose_name="Pump time", help_text="Amount of time to run the pump for to dispence 1 of these units", blank=True, ) class Meta: constraints = [ models.CheckConstraint( condition=Q(pump_time__isnull=False) | Q(valve_time__isnull=False), name='one_of_valve_time_or_pump_time_must_be_filled' ), ] def __str__(self): return self.abbreviation class Ingredient(models.Model): bottle = models.ForeignKey( verbose_name="Bottle", help_text="This ingredient's bottle", to=Bottle, on_delete=models.CASCADE ) drink = models.ForeignKey( verbose_name="Drink", help_text="The drink this ingredient is part of", to=Drink, on_delete=models.CASCADE ) amount = models.FloatField( verbose_name="Amount", help_text="In conjunction with unit it is an absolute amount", ) unit = models.ForeignKey( verbose_name="Unit", help_text="The unit that the ammount is messured in, e.g. ml.", to=Unit, on_delete=models.CASCADE, ) optional = models.BooleanField( verbose_name="Optional", help_text="Whether an ingredient is optinal", ) @property def name(self) -> str: """ e.g: 3cl. Jägermeister """ return f"{self.amount}{self.unit} {self.bottle}" def __str__(self) -> str: """ Name with drink context, for admin overview. E.g: Kung Fu 3cl. Jägermeister """ return f"{self.drink} {self.name}"