1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
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}"
|