diff --git a/cookbook/admin.py b/cookbook/admin.py index e667a1614..6fc1d1408 100644 --- a/cookbook/admin.py +++ b/cookbook/admin.py @@ -172,3 +172,10 @@ class ShareLinkAdmin(admin.ModelAdmin): admin.site.register(ShareLink, ShareLinkAdmin) + + +class NutritionInformationAdmin(admin.ModelAdmin): + list_display = ('id',) + + +admin.site.register(NutritionInformation, NutritionInformationAdmin) diff --git a/cookbook/migrations/0089_auto_20201117_2222.py b/cookbook/migrations/0089_auto_20201117_2222.py new file mode 100644 index 000000000..5e5dca9cf --- /dev/null +++ b/cookbook/migrations/0089_auto_20201117_2222.py @@ -0,0 +1,36 @@ +# Generated by Django 3.1.1 on 2020-11-17 21:22 + +import datetime +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0088_shoppinglist_finished'), + ] + + operations = [ + migrations.CreateModel( + name='NutritionInformation', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('fats', models.DecimalField(decimal_places=16, default=0, max_digits=32)), + ('carbohydrates', models.DecimalField(decimal_places=16, default=0, max_digits=32)), + ('proteins', models.DecimalField(decimal_places=16, default=0, max_digits=32)), + ('calories', models.DecimalField(decimal_places=16, default=0, max_digits=32)), + ('source', models.CharField(blank=True, default='', max_length=512, null=True)), + ], + ), + migrations.AlterField( + model_name='invitelink', + name='valid_until', + field=models.DateField(default=datetime.date(2020, 12, 1)), + ), + migrations.AddField( + model_name='recipe', + name='nutrition', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.nutritioninformation'), + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index 875836bed..2dc4689d9 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -182,6 +182,17 @@ class Step(models.Model): ordering = ['order', 'pk'] +class NutritionInformation(models.Model): + fats = models.DecimalField(default=0, decimal_places=16, max_digits=32) + carbohydrates = models.DecimalField(default=0, decimal_places=16, max_digits=32) + proteins = models.DecimalField(default=0, decimal_places=16, max_digits=32) + calories = models.DecimalField(default=0, decimal_places=16, max_digits=32) + source = models.CharField(max_length=512, default="", null=True, blank=True) + + def __str__(self): + return f'Nutrition' + + class Recipe(models.Model): name = models.CharField(max_length=128) image = models.ImageField(upload_to='recipes/', blank=True, null=True) @@ -195,6 +206,7 @@ class Recipe(models.Model): working_time = models.IntegerField(default=0) waiting_time = models.IntegerField(default=0) internal = models.BooleanField(default=False) + nutrition = models.ForeignKey(NutritionInformation, blank=True, null=True, on_delete=models.CASCADE) created_by = models.ForeignKey(User, on_delete=models.PROTECT) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 8f5a115d3..2fbf11c4d 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -6,7 +6,7 @@ from rest_framework import serializers from rest_framework.exceptions import ValidationError from cookbook.models import MealPlan, MealType, Recipe, ViewLog, UserPreference, Storage, Sync, SyncLog, Keyword, Unit, Ingredient, Comment, RecipeImport, RecipeBook, RecipeBookEntry, ShareLink, CookLog, Food, Step, ShoppingList, \ - ShoppingListEntry, ShoppingListRecipe + ShoppingListEntry, ShoppingListRecipe, NutritionInformation from cookbook.templatetags.custom_tags import markdown @@ -140,13 +140,20 @@ class StepSerializer(WritableNestedModelSerializer): fields = ('id', 'name', 'type', 'instruction', 'ingredients', 'time', 'order', 'show_as_header') +class NutritionInformationSerializer(serializers.ModelSerializer): + class Meta: + model = NutritionInformation + fields = ('carbohydrates', 'fats', 'proteins', 'calories', 'source') + + class RecipeSerializer(WritableNestedModelSerializer): + nutrition = NutritionInformationSerializer(allow_null=True) steps = StepSerializer(many=True) keywords = KeywordSerializer(many=True) class Meta: model = Recipe - fields = ['id', 'name', 'image', 'keywords', 'steps', 'working_time', 'waiting_time', 'created_by', 'created_at', 'updated_at', 'internal'] + fields = ['id', 'name', 'image', 'keywords', 'steps', 'working_time', 'waiting_time', 'created_by', 'created_at', 'updated_at', 'internal', 'nutrition'] read_only_fields = ['image', 'created_by', 'created_at'] diff --git a/cookbook/templates/forms/edit_internal_recipe.html b/cookbook/templates/forms/edit_internal_recipe.html index d890a78a3..50574fcc2 100644 --- a/cookbook/templates/forms/edit_internal_recipe.html +++ b/cookbook/templates/forms/edit_internal_recipe.html @@ -81,6 +81,34 @@ +
| + {% trans 'Calories' %} + | +{{ recipe.nutrition.calories|floatformat:2 }} | +kcal | +
| + {% trans 'Carbohydrates' %} + | +{{ recipe.nutrition.carbohydrates|floatformat:2 }} | +g | +
| + {% trans 'Fats' %} + | +{{ recipe.nutrition.fats|floatformat:2 }} | +g | +
| + {% trans 'Proteins' %} + | +{{ recipe.nutrition.proteins|floatformat:2 }} | +g | +
| + | + | + |