diff --git a/reinheit/apps/brew/admin.py b/reinheit/apps/brew/admin.py index 775a611..157c18e 100644 --- a/reinheit/apps/brew/admin.py +++ b/reinheit/apps/brew/admin.py @@ -1,17 +1,33 @@ from django.contrib import admin -from .models import Brew, Addition +from .models import Brew, YeastAddition, FermentableAddition, MaltAddition, ChemicalAddition # Register your models here. -class AdditionInline(admin.TabularInline): - model = Addition +class MaltAdditionInline(admin.TabularInline): + model = MaltAddition + extra = 1 + + +class FermentableAdditionInline(admin.TabularInline): + model = FermentableAddition + extra = 0 + + +class ChemicalAdditionInline(admin.TabularInline): + model = ChemicalAddition + extra = 0 + + +class YeastAdditionInline(admin.TabularInline): + model = YeastAddition + extra = 0 @admin.register(Brew) class BrewAdmin(admin.ModelAdmin): - inlines = [AdditionInline] + inlines = [MaltAdditionInline, FermentableAdditionInline, ChemicalAdditionInline, YeastAdditionInline] list_display = ["name", "style", "pitch_date"] date_hierarchy = "pitch_date" diff --git a/reinheit/apps/brew/migrations/0005_fermentableaddition_maltaddition_yeastaddition_and_more.py b/reinheit/apps/brew/migrations/0005_fermentableaddition_maltaddition_yeastaddition_and_more.py new file mode 100644 index 0000000..181d63f --- /dev/null +++ b/reinheit/apps/brew/migrations/0005_fermentableaddition_maltaddition_yeastaddition_and_more.py @@ -0,0 +1,104 @@ +# Generated by Django 5.0.6 on 2024-06-26 20:49 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("brew", "0004_brew_final_gravity_brew_original_gravity_and_more"), + ] + + operations = [ + migrations.CreateModel( + name="FermentableAddition", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("mass", models.FloatField(help_text="The mass of ingredient added")), + ("added", models.DateTimeField(null=True)), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="MaltAddition", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("mass", models.FloatField(help_text="The mass of ingredient added")), + ("added", models.DateTimeField(null=True)), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="YeastAddition", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("mass", models.FloatField(help_text="The mass of ingredient added")), + ("added", models.DateTimeField(null=True)), + ], + options={ + "abstract": False, + }, + ), + migrations.RemoveField( + model_name="addition", + name="brew", + ), + migrations.RemoveField( + model_name="addition", + name="ingredient", + ), + migrations.CreateModel( + name="ChemicalAddition", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("mass", models.FloatField(help_text="The mass of ingredient added")), + ("added", models.DateTimeField(null=True)), + ( + "brew", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="brew.brew" + ), + ), + ], + options={ + "abstract": False, + }, + ), + ] diff --git a/reinheit/apps/brew/migrations/0006_chemicaladdition_ingredient_fermentableaddition_brew_and_more.py b/reinheit/apps/brew/migrations/0006_chemicaladdition_ingredient_fermentableaddition_brew_and_more.py new file mode 100644 index 0000000..436f6c8 --- /dev/null +++ b/reinheit/apps/brew/migrations/0006_chemicaladdition_ingredient_fermentableaddition_brew_and_more.py @@ -0,0 +1,69 @@ +# Generated by Django 5.0.6 on 2024-06-26 20:49 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("brew", "0005_fermentableaddition_maltaddition_yeastaddition_and_more"), + ("ingredients", "0006_chemical_fermentable_malt_yeast_delete_ingredient"), + ] + + operations = [ + migrations.AddField( + model_name="chemicaladdition", + name="ingredient", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="ingredients.chemical" + ), + ), + migrations.AddField( + model_name="fermentableaddition", + name="brew", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="brew.brew" + ), + ), + migrations.AddField( + model_name="fermentableaddition", + name="ingredient", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="ingredients.fermentable", + ), + ), + migrations.AddField( + model_name="maltaddition", + name="brew", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="brew.brew" + ), + ), + migrations.AddField( + model_name="maltaddition", + name="ingredient", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + to="ingredients.fermentable", + ), + ), + migrations.AddField( + model_name="yeastaddition", + name="brew", + field=models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, to="brew.brew" + ), + ), + migrations.AddField( + model_name="yeastaddition", + name="ingredient", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="ingredients.yeast" + ), + ), + migrations.DeleteModel( + name="Addition", + ), + ] diff --git a/reinheit/apps/brew/migrations/0007_alter_maltaddition_ingredient.py b/reinheit/apps/brew/migrations/0007_alter_maltaddition_ingredient.py new file mode 100644 index 0000000..11f377f --- /dev/null +++ b/reinheit/apps/brew/migrations/0007_alter_maltaddition_ingredient.py @@ -0,0 +1,22 @@ +# Generated by Django 5.0.6 on 2024-06-26 20:52 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("brew", "0006_chemicaladdition_ingredient_fermentableaddition_brew_and_more"), + ("ingredients", "0006_chemical_fermentable_malt_yeast_delete_ingredient"), + ] + + operations = [ + migrations.AlterField( + model_name="maltaddition", + name="ingredient", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, to="ingredients.malt" + ), + ), + ] diff --git a/reinheit/apps/brew/models.py b/reinheit/apps/brew/models.py index 8726199..556619c 100644 --- a/reinheit/apps/brew/models.py +++ b/reinheit/apps/brew/models.py @@ -38,20 +38,34 @@ class Brew(models.Model): return f"{self.style}: {self.name}" -class Addition(models.Model): - ingredient = models.ForeignKey("ingredients.Ingredient", on_delete=models.PROTECT) - brew = models.ForeignKey("Brew", on_delete=models.CASCADE, related_name="additions") +class AbstractAddition(models.Model): + brew = models.ForeignKey("Brew", on_delete=models.CASCADE) - mass = models.FloatField(help_text="The mass in kg added") + mass = models.FloatField(help_text="The mass of ingredient added") added = models.DateTimeField(null=True) @property def unit(self): - return "g" if self.mass < 0.5 else "kg" - - @property - def humanised_mass(self): - return 1000 * self.mass if self.mass < 0.5 else self.mass + return self.ingredient.UNIT def __str__(self): - return f"{self.mass}kg of {self.ingredient} in {self.brew}" + return f"{self.mass}{self.unit} of {self.ingredient} in {self.brew}" + + class Meta: + abstract = True + + +class YeastAddition(AbstractAddition): + ingredient = models.ForeignKey("ingredients.Yeast", on_delete=models.PROTECT) + + +class FermentableAddition(AbstractAddition): + ingredient = models.ForeignKey("ingredients.Fermentable", on_delete=models.PROTECT) + + +class MaltAddition(AbstractAddition): + ingredient = models.ForeignKey("ingredients.Malt", on_delete=models.PROTECT) + + +class ChemicalAddition(AbstractAddition): + ingredient = models.ForeignKey("ingredients.Chemical", on_delete=models.PROTECT) diff --git a/reinheit/apps/brew/views.py b/reinheit/apps/brew/views.py index cc7a057..46e659a 100644 --- a/reinheit/apps/brew/views.py +++ b/reinheit/apps/brew/views.py @@ -12,13 +12,3 @@ class BrewListView(ListView): class BrewView(DetailView): model = Brew - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - for value, label in Ingredient.Type.choices: - print(label, value) - context[label] = self.object.additions.filter(ingredient__kind=value) - - context["ingredient_types"] = Ingredient.Type.names - - return context diff --git a/reinheit/apps/ingredients/admin.py b/reinheit/apps/ingredients/admin.py index 9717638..a42b37a 100644 --- a/reinheit/apps/ingredients/admin.py +++ b/reinheit/apps/ingredients/admin.py @@ -1,24 +1,23 @@ from django.contrib import admin -from .models import Ingredient, Producer +from .models import Producer, Yeast, Fermentable, Malt, Chemical # Register your models here. -@admin.register(Ingredient) class IngredientAdmin(admin.ModelAdmin): - list_display = ["name", "kind", "producer"] - list_filter = ["kind", "producer"] + list_display = ["name", "producer"] + list_filter = ["producer"] - search_fields = ["name", "kind", "producer__name"] - - -class IngredientInline(admin.TabularInline): - model = Ingredient - extra = 1 + search_fields = ["name", "producer__name"] @admin.register(Producer) class ProducerAdmin(admin.ModelAdmin): list_display = ["name"] - inlines = [IngredientInline] + + +admin.site.register(Yeast, IngredientAdmin) +admin.site.register(Fermentable, IngredientAdmin) +admin.site.register(Malt, IngredientAdmin) +admin.site.register(Chemical, IngredientAdmin) diff --git a/reinheit/apps/ingredients/migrations/0006_chemical_fermentable_malt_yeast_delete_ingredient.py b/reinheit/apps/ingredients/migrations/0006_chemical_fermentable_malt_yeast_delete_ingredient.py new file mode 100644 index 0000000..09d7549 --- /dev/null +++ b/reinheit/apps/ingredients/migrations/0006_chemical_fermentable_malt_yeast_delete_ingredient.py @@ -0,0 +1,145 @@ +# Generated by Django 5.0.6 on 2024-06-26 20:49 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("brew", "0005_fermentableaddition_maltaddition_yeastaddition_and_more"), + ("ingredients", "0005_alter_ingredient_kind"), + ] + + operations = [ + migrations.CreateModel( + name="Chemical", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ( + "description", + models.CharField(blank=True, default="", max_length=255), + ), + ( + "producer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="ingredients.producer", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Fermentable", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ( + "description", + models.CharField(blank=True, default="", max_length=255), + ), + ( + "producer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="ingredients.producer", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Malt", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ( + "description", + models.CharField(blank=True, default="", max_length=255), + ), + ( + "kind", + models.CharField( + choices=[ + ("DME", "Dry Malt Extract"), + ("LME", "Liquid Malt Extract"), + ("MALT", "Malted Grain"), + ], + max_length=4, + ), + ), + ( + "producer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="ingredients.producer", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.CreateModel( + name="Yeast", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ( + "description", + models.CharField(blank=True, default="", max_length=255), + ), + ( + "producer", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to="ingredients.producer", + ), + ), + ], + options={ + "abstract": False, + }, + ), + migrations.DeleteModel( + name="Ingredient", + ), + ] diff --git a/reinheit/apps/ingredients/models.py b/reinheit/apps/ingredients/models.py index 1ae0d98..37a7fc2 100644 --- a/reinheit/apps/ingredients/models.py +++ b/reinheit/apps/ingredients/models.py @@ -5,20 +5,12 @@ from django.db import models class Ingredient(models.Model): - class Type(models.TextChoices): - YEAST = "YEAST", "Yeast" - FERMENTABLE = "FERM", "Fermentable" - HOP = "HOP", "Hop" - CHEMICAL = "CHEM", "Chemical" - - kind = models.CharField(max_length=5, choices=Type) - name = models.CharField(max_length=255) description = models.CharField(max_length=255, blank=True, default="") producer = models.ForeignKey("Producer", on_delete=models.CASCADE) - def __str__(self): - return f"{self.get_kind_display()}: {self.name}" + class Meta: + abstract = True class Producer(models.Model): @@ -26,3 +18,38 @@ class Producer(models.Model): def __str__(self): return self.name + + +class Yeast(Ingredient): + UNIT = "g" + + def __str__(self): + return f"Yeast: {self.name}" + + +class Chemical(Ingredient): + UNIT = "g" + + def __str__(self): + return f"Chemical: {self.name}" + + +class Malt(Ingredient): + class Type(models.TextChoices): + DME = "DME", "Dry Malt Extract" + LME = "LME", "Liquid Malt Extract" + MALT = "MALT", "Malted Grain" + + UNIT = "kg" + + kind = models.CharField(max_length=4, choices=Type) + + def __str__(self): + return f"Malt: {self.name}" + + +class Fermentable(Ingredient): + UNIT = "kg" + + def __str__(self): + return f"Other Fermentable: {self.name}" diff --git a/reinheit/templates/brew/brew_detail.html b/reinheit/templates/brew/brew_detail.html index 298d68a..79b27ea 100644 --- a/reinheit/templates/brew/brew_detail.html +++ b/reinheit/templates/brew/brew_detail.html @@ -7,20 +7,20 @@
{{ object.notes }}