From 018fcf27eaaed8ac7835845e7d94f5c04018da8d Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Tue, 15 Jun 2021 22:56:25 +0200 Subject: [PATCH] migrated space to ingredient, step and nutritional value --- .../migrations/0135_auto_20210615_2210.py | 63 +++++++++++++++++++ cookbook/models.py | 32 +++------- cookbook/serializer.py | 13 ++++ cookbook/tests/api/test_api_ingredient.py | 5 +- cookbook/tests/api/test_api_step.py | 5 +- cookbook/tests/conftest.py | 6 +- 6 files changed, 95 insertions(+), 29 deletions(-) create mode 100644 cookbook/migrations/0135_auto_20210615_2210.py diff --git a/cookbook/migrations/0135_auto_20210615_2210.py b/cookbook/migrations/0135_auto_20210615_2210.py new file mode 100644 index 000000000..a82c658cb --- /dev/null +++ b/cookbook/migrations/0135_auto_20210615_2210.py @@ -0,0 +1,63 @@ +# Generated by Django 3.2.4 on 2021-06-15 20:10 + +from django.db import migrations +from django.db.models import Subquery, OuterRef +from django_scopes import scopes_disabled +from django.db import migrations, models +import django.db.models.deletion + + +def migrate_spaces(apps, schema_editor): + with scopes_disabled(): + Recipe = apps.get_model('cookbook', 'Recipe') + Step = apps.get_model('cookbook', 'Step') + Ingredient = apps.get_model('cookbook', 'Ingredient') + NutritionInformation = apps.get_model('cookbook', 'NutritionInformation') + + Step.objects.filter(recipe__isnull=True).delete() + Ingredient.objects.filter(step__recipe__isnull=True).delete() + NutritionInformation.objects.filter(recipe__isnull=True).delete() + + Step.objects.update(space=Subquery(Step.objects.filter(pk=OuterRef('pk')).values('recipe__space')[:1])) + Ingredient.objects.update(space=Subquery(Ingredient.objects.filter(pk=OuterRef('pk')).values('step__recipe__space')[:1])) + NutritionInformation.objects.update(space=Subquery(NutritionInformation.objects.filter(pk=OuterRef('pk')).values('recipe__space')[:1])) + + +class Migration(migrations.Migration): + dependencies = [ + ('cookbook', '0134_space_allow_sharing'), + ] + + operations = [ + migrations.AddField( + model_name='ingredient', + name='space', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space', null=True), + ), + migrations.AddField( + model_name='nutritioninformation', + name='space', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space', null=True), + ), + migrations.AddField( + model_name='step', + name='space', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space', null=True), + ), + migrations.RunPython(migrate_spaces), + migrations.AlterField( + model_name='ingredient', + name='space', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space'), + ), + migrations.AlterField( + model_name='nutritioninformation', + name='space', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space'), + ), + migrations.AlterField( + model_name='step', + name='space', + field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space'), + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index 3297ac8e7..a9b9f04f1 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -315,14 +315,8 @@ class Ingredient(ExportModelOperationsMixin('ingredient'), models.Model, Permiss no_amount = models.BooleanField(default=False) order = models.IntegerField(default=0) - objects = ScopedManager(space='step__recipe__space') - - @staticmethod - def get_space_key(): - return 'step', 'recipe', 'space' - - def get_space(self): - return self.step_set.first().recipe_set.first().space + space = models.ForeignKey(Space, on_delete=models.CASCADE) + objects = ScopedManager(space='space') def __str__(self): return str(self.amount) + ' ' + str(self.unit) + ' ' + str(self.food) @@ -349,14 +343,8 @@ class Step(ExportModelOperationsMixin('step'), models.Model, PermissionModelMixi file = models.ForeignKey('UserFile', on_delete=models.PROTECT, null=True, blank=True) show_as_header = models.BooleanField(default=True) - objects = ScopedManager(space='recipe__space') - - @staticmethod - def get_space_key(): - return 'recipe', 'space' - - def get_space(self): - return self.recipe_set.first().space + space = models.ForeignKey(Space, on_delete=models.CASCADE) + objects = ScopedManager(space='space') def get_instruction_render(self): from cookbook.helper.template_helper import render_instructions @@ -377,17 +365,11 @@ class NutritionInformation(models.Model, PermissionModelMixin): max_length=512, default="", null=True, blank=True ) - objects = ScopedManager(space='recipe__space') - - @staticmethod - def get_space_key(): - return 'recipe', 'space' - - def get_space(self): - return self.recipe_set.first().space + space = models.ForeignKey(Space, on_delete=models.CASCADE) + objects = ScopedManager(space='space') def __str__(self): - return 'Nutrition' + return f'Nutrition {self.pk}' class Recipe(ExportModelOperationsMixin('recipe'), models.Model, PermissionModelMixin): diff --git a/cookbook/serializer.py b/cookbook/serializer.py index 55ead3218..43c73b58c 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -283,6 +283,10 @@ class IngredientSerializer(WritableNestedModelSerializer): unit = UnitSerializer(allow_null=True) amount = CustomDecimalField() + def create(self, validated_data): + validated_data['space'] = self.context['request'].space + return super().create(validated_data) + class Meta: model = Ingredient fields = ( @@ -297,6 +301,10 @@ class StepSerializer(WritableNestedModelSerializer): ingredients_vue = serializers.SerializerMethodField('get_ingredients_vue') file = UserFileViewSerializer(allow_null=True, required=False) + def create(self, validated_data): + validated_data['space'] = self.context['request'].space + return super().create(validated_data) + def get_ingredients_vue(self, obj): return obj.get_instruction_render() @@ -312,6 +320,11 @@ class StepSerializer(WritableNestedModelSerializer): class NutritionInformationSerializer(serializers.ModelSerializer): + + def create(self, validated_data): + validated_data['space'] = self.context['request'].space + return super().create(validated_data) + class Meta: model = NutritionInformation fields = ('id', 'carbohydrates', 'fats', 'proteins', 'calories', 'source') diff --git a/cookbook/tests/api/test_api_ingredient.py b/cookbook/tests/api/test_api_ingredient.py index 061994914..cde3d65a9 100644 --- a/cookbook/tests/api/test_api_ingredient.py +++ b/cookbook/tests/api/test_api_ingredient.py @@ -1,10 +1,11 @@ import json import pytest +from django.db.models import Subquery, OuterRef from django.urls import reverse from django_scopes import scopes_disabled -from cookbook.models import Ingredient +from cookbook.models import Ingredient, Step LIST_URL = 'api:ingredient-list' DETAIL_URL = 'api:ingredient-detail' @@ -28,6 +29,8 @@ def test_list_space(recipe_1_s1, u1_s1, u1_s2, space_2): with scopes_disabled(): recipe_1_s1.space = space_2 recipe_1_s1.save() + Step.objects.update(space=Subquery(Step.objects.filter(pk=OuterRef('pk')).values('recipe__space')[:1])) + Ingredient.objects.update(space=Subquery(Ingredient.objects.filter(pk=OuterRef('pk')).values('step__recipe__space')[:1])) assert len(json.loads(u1_s1.get(reverse(LIST_URL)).content)) == 0 assert len(json.loads(u1_s2.get(reverse(LIST_URL)).content)) == 10 diff --git a/cookbook/tests/api/test_api_step.py b/cookbook/tests/api/test_api_step.py index dc755b2de..c34b202a8 100644 --- a/cookbook/tests/api/test_api_step.py +++ b/cookbook/tests/api/test_api_step.py @@ -1,10 +1,11 @@ import json import pytest +from django.db.models import Subquery, OuterRef from django.urls import reverse from django_scopes import scopes_disabled -from cookbook.models import Step +from cookbook.models import Step, Ingredient LIST_URL = 'api:step-list' DETAIL_URL = 'api:step-detail' @@ -28,6 +29,8 @@ def test_list_space(recipe_1_s1, u1_s1, u1_s2, space_2): with scopes_disabled(): recipe_1_s1.space = space_2 recipe_1_s1.save() + Step.objects.update(space=Subquery(Step.objects.filter(pk=OuterRef('pk')).values('recipe__space')[:1])) + Ingredient.objects.update(space=Subquery(Ingredient.objects.filter(pk=OuterRef('pk')).values('step__recipe__space')[:1])) assert len(json.loads(u1_s1.get(reverse(LIST_URL)).content)) == 0 assert len(json.loads(u1_s2.get(reverse(LIST_URL)).content)) == 2 diff --git a/cookbook/tests/conftest.py b/cookbook/tests/conftest.py index 8ab9dc513..54d87c1c9 100644 --- a/cookbook/tests/conftest.py +++ b/cookbook/tests/conftest.py @@ -51,8 +51,8 @@ def get_random_recipe(space_1, u1_s1): internal=True, ) - s1 = Step.objects.create(name=uuid.uuid4(), instruction=uuid.uuid4(), ) - s2 = Step.objects.create(name=uuid.uuid4(), instruction=uuid.uuid4(), ) + s1 = Step.objects.create(name=uuid.uuid4(), instruction=uuid.uuid4(), space=space_1, ) + s2 = Step.objects.create(name=uuid.uuid4(), instruction=uuid.uuid4(), space=space_1, ) r.steps.add(s1) r.steps.add(s2) @@ -64,6 +64,7 @@ def get_random_recipe(space_1, u1_s1): food=Food.objects.create(name=uuid.uuid4(), space=space_1, ), unit=Unit.objects.create(name=uuid.uuid4(), space=space_1, ), note=uuid.uuid4(), + space=space_1, ) ) @@ -73,6 +74,7 @@ def get_random_recipe(space_1, u1_s1): food=Food.objects.create(name=uuid.uuid4(), space=space_1, ), unit=Unit.objects.create(name=uuid.uuid4(), space=space_1, ), note=uuid.uuid4(), + space=space_1, ) )