diff --git a/cookbook/helper/dal.py b/cookbook/helper/dal.py index 2b448b06..3b74b227 100644 --- a/cookbook/helper/dal.py +++ b/cookbook/helper/dal.py @@ -1,6 +1,6 @@ from dal import autocomplete -from cookbook.models import Keyword, RecipeIngredients, Recipe, Unit +from cookbook.models import Keyword, RecipeIngredient, Recipe, Unit class KeywordAutocomplete(autocomplete.Select2QuerySetView): @@ -19,9 +19,9 @@ class KeywordAutocomplete(autocomplete.Select2QuerySetView): class IngredientsAutocomplete(autocomplete.Select2QuerySetView): def get_queryset(self): if not self.request.user.is_authenticated: - return RecipeIngredients.objects.none() + return RecipeIngredient.objects.none() - qs = RecipeIngredients.objects.all() + qs = RecipeIngredient.objects.all() if self.q: qs = qs.filter(name__istartswith=self.q) diff --git a/cookbook/migrations/0010_auto_20200130_1059.py b/cookbook/migrations/0010_auto_20200130_1059.py index 3ef2f066..5705aff4 100644 --- a/cookbook/migrations/0010_auto_20200130_1059.py +++ b/cookbook/migrations/0010_auto_20200130_1059.py @@ -5,14 +5,14 @@ from django.db import migrations def migrate_ingredient_units(apps, schema_editor): Unit = apps.get_model('cookbook', 'Unit') - RecipeIngredients = apps.get_model('cookbook', 'RecipeIngredients') + RecipeIngredient = apps.get_model('cookbook', 'RecipeIngredient') - for u in RecipeIngredients.objects.values('unit').distinct(): + for u in RecipeIngredient.objects.values('unit').distinct(): unit = Unit() unit.name = u['unit'] unit.save() - for i in RecipeIngredients.objects.all(): + for i in RecipeIngredient.objects.all(): i.unit_key = Unit.objects.get(name=i.unit) i.save() diff --git a/cookbook/migrations/0018_auto_20200216_2303.py b/cookbook/migrations/0018_auto_20200216_2303.py new file mode 100644 index 00000000..0b14ebb4 --- /dev/null +++ b/cookbook/migrations/0018_auto_20200216_2303.py @@ -0,0 +1,17 @@ +# Generated by Django 3.0.2 on 2020-02-16 22:03 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0017_auto_20200216_2257'), + ] + + operations = [ + migrations.RenameModel( + old_name='RecipeIngredients', + new_name='RecipeIngredient', + ), + ] diff --git a/cookbook/migrations/0019_ingredient.py b/cookbook/migrations/0019_ingredient.py new file mode 100644 index 00000000..8ba14140 --- /dev/null +++ b/cookbook/migrations/0019_ingredient.py @@ -0,0 +1,20 @@ +# Generated by Django 3.0.2 on 2020-02-16 22:03 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0018_auto_20200216_2303'), + ] + + operations = [ + migrations.CreateModel( + name='Ingredient', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=128, unique=True)), + ], + ), + ] diff --git a/cookbook/migrations/0020_recipeingredient_ingredient.py b/cookbook/migrations/0020_recipeingredient_ingredient.py new file mode 100644 index 00000000..4beb0668 --- /dev/null +++ b/cookbook/migrations/0020_recipeingredient_ingredient.py @@ -0,0 +1,19 @@ +# Generated by Django 3.0.2 on 2020-02-16 22:08 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0019_ingredient'), + ] + + operations = [ + migrations.AddField( + model_name='recipeingredient', + name='ingredient', + field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.PROTECT, to='cookbook.Ingredient'), + ), + ] diff --git a/cookbook/migrations/0021_auto_20200216_2309.py b/cookbook/migrations/0021_auto_20200216_2309.py new file mode 100644 index 00000000..1d111549 --- /dev/null +++ b/cookbook/migrations/0021_auto_20200216_2309.py @@ -0,0 +1,26 @@ +# Generated by Django 3.0.2 on 2020-02-16 22:09 +from django.db import migrations + + +def migrate_ingredients(apps, schema_editor): + Ingredient = apps.get_model('cookbook', 'Ingredient') + RecipeIngredient = apps.get_model('cookbook', 'RecipeIngredient') + + for u in RecipeIngredient.objects.values('name').distinct(): + ingredient = Ingredient() + ingredient.name = u['name'] + ingredient.save() + + for i in RecipeIngredient.objects.all(): + i.ingredient = Ingredient.objects.get(name=i.name) + i.save() + + +class Migration(migrations.Migration): + dependencies = [ + ('cookbook', '0020_recipeingredient_ingredient'), + ] + + operations = [ + migrations.RunPython(migrate_ingredients), + ] diff --git a/cookbook/migrations/0022_remove_recipeingredient_name.py b/cookbook/migrations/0022_remove_recipeingredient_name.py new file mode 100644 index 00000000..ed2de07b --- /dev/null +++ b/cookbook/migrations/0022_remove_recipeingredient_name.py @@ -0,0 +1,17 @@ +# Generated by Django 3.0.2 on 2020-02-16 22:11 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0021_auto_20200216_2309'), + ] + + operations = [ + migrations.RemoveField( + model_name='recipeingredient', + name='name', + ), + ] diff --git a/cookbook/migrations/0023_auto_20200216_2311.py b/cookbook/migrations/0023_auto_20200216_2311.py new file mode 100644 index 00000000..e3a42c2f --- /dev/null +++ b/cookbook/migrations/0023_auto_20200216_2311.py @@ -0,0 +1,18 @@ +# Generated by Django 3.0.2 on 2020-02-16 22:11 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('cookbook', '0022_remove_recipeingredient_name'), + ] + + operations = [ + migrations.RenameField( + model_name='recipeingredient', + old_name='ingredient', + new_name='name', + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index 2bdd41ca..83420cf1 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -95,14 +95,21 @@ class Unit(models.Model): return self.name -class RecipeIngredients(models.Model): - name = models.CharField(max_length=128) +class Ingredient(models.Model): + name = models.CharField(unique=True, max_length=128) + + def __str__(self): + return self.name + + +class RecipeIngredient(models.Model): + name = models.ForeignKey(Ingredient, on_delete=models.PROTECT, null=True) recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE) unit = models.ForeignKey(Unit, on_delete=models.PROTECT, null=True) amount = models.DecimalField(default=0, decimal_places=2, max_digits=16) def __str__(self): - return str(self.amount) + ' ' + str(self.unit) + ' ' + self.name + return str(self.amount) + ' ' + str(self.unit) + ' ' + str(self.name) class Comment(models.Model): diff --git a/cookbook/tests/test_views.py b/cookbook/tests/test_views.py index 84bb0260..e6e34eea 100644 --- a/cookbook/tests/test_views.py +++ b/cookbook/tests/test_views.py @@ -3,7 +3,7 @@ from django.contrib.auth.models import User from django.test import TestCase, Client from django.urls import reverse -from cookbook.models import Recipe, RecipeIngredients +from cookbook.models import Recipe, RecipeIngredient class TestViews(TestCase): @@ -69,4 +69,4 @@ class TestViews(TestCase): r = self.client.post(url, {'name': 'Changed', 'working_time': 15, 'waiting_time': 15, 'ingredients': '[{"name":"Tomato","unit__name":"g","amount":100,"delete":false},{"name":"Egg","unit__name":"Piece","amount":2,"delete":false}]'}) self.assertEqual(r.status_code, 200) - self.assertEqual(2, RecipeIngredients.objects.filter(recipe=recipe).count()) + self.assertEqual(2, RecipeIngredient.objects.filter(recipe=recipe).count()) diff --git a/cookbook/views/edit.py b/cookbook/views/edit.py index 2165a820..85d8309b 100644 --- a/cookbook/views/edit.py +++ b/cookbook/views/edit.py @@ -16,7 +16,7 @@ from django.views.generic import UpdateView, DeleteView from cookbook.forms import ExternalRecipeForm, KeywordForm, StorageForm, SyncForm, InternalRecipeForm, CommentForm, \ MealPlanForm, UnitMergeForm -from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage, Comment, RecipeIngredients, RecipeBook, \ +from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage, Comment, RecipeIngredient, RecipeBook, \ RecipeBookEntry, MealPlan, Unit from cookbook.provider.dropbox import Dropbox from cookbook.provider.nextcloud import Nextcloud @@ -75,10 +75,10 @@ def internal_recipe_update(request, pk): recipe.save() form_ingredients = json.loads(form.cleaned_data['ingredients']) - RecipeIngredients.objects.filter(recipe=recipe_instance).delete() + RecipeIngredient.objects.filter(recipe=recipe_instance).delete() for i in form_ingredients: - ingredient = RecipeIngredients() + ingredient = RecipeIngredient() ingredient.recipe = recipe_instance ingredient.name = i['name'] if isinstance(i['amount'], str): @@ -105,7 +105,7 @@ def internal_recipe_update(request, pk): else: form = InternalRecipeForm(instance=recipe_instance) - ingredients = RecipeIngredients.objects.select_related('unit__name').filter(recipe=recipe_instance).values('name', + ingredients = RecipeIngredient.objects.select_related('unit__name').filter(recipe=recipe_instance).values('name', 'unit__name', 'amount') @@ -300,7 +300,7 @@ def edit_ingredients(request): if form.is_valid(): new_unit = form.cleaned_data['new_unit'] old_unit = form.cleaned_data['old_unit'] - ingredients = RecipeIngredients.objects.filter(unit=old_unit).all() + ingredients = RecipeIngredient.objects.filter(unit=old_unit).all() for i in ingredients: i.unit = new_unit i.save() diff --git a/cookbook/views/views.py b/cookbook/views/views.py index de53562a..1ecec82e 100644 --- a/cookbook/views/views.py +++ b/cookbook/views/views.py @@ -28,7 +28,7 @@ def index(request): @login_required def recipe_view(request, pk): recipe = get_object_or_404(Recipe, pk=pk) - ingredients = RecipeIngredients.objects.filter(recipe=recipe) + ingredients = RecipeIngredient.objects.filter(recipe=recipe) comments = Comment.objects.filter(recipe=recipe) if request.method == "POST": @@ -137,7 +137,7 @@ def shopping_list(request): ingredients = [] for r in recipes: - for i in RecipeIngredients.objects.filter(recipe=r).all(): + for i in RecipeIngredient.objects.filter(recipe=r).all(): ingredients.append(i) return render(request, 'shopping_list.html', {'ingredients': ingredients, 'recipes': recipes, 'form': form})