diff --git a/cookbook/migrations/0233_food_shopping_lists_shoppinglistentry_shopping_lists_and_more.py b/cookbook/migrations/0233_food_shopping_lists_shoppinglistentry_shopping_lists_and_more.py
new file mode 100644
index 000000000..52ec8ac05
--- /dev/null
+++ b/cookbook/migrations/0233_food_shopping_lists_shoppinglistentry_shopping_lists_and_more.py
@@ -0,0 +1,28 @@
+# Generated by Django 5.2.7 on 2025-11-30 14:00
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('cookbook', '0232_shoppinglist'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='food',
+ name='shopping_lists',
+ field=models.ManyToManyField(blank=True, to='cookbook.shoppinglist'),
+ ),
+ migrations.AddField(
+ model_name='shoppinglistentry',
+ name='shopping_lists',
+ field=models.ManyToManyField(blank=True, to='cookbook.shoppinglist'),
+ ),
+ migrations.AddField(
+ model_name='supermarket',
+ name='shopping_lists',
+ field=models.ManyToManyField(blank=True, to='cookbook.shoppinglist'),
+ ),
+ ]
diff --git a/cookbook/models.py b/cookbook/models.py
index 32b0e988e..91f9a0dfc 100644
--- a/cookbook/models.py
+++ b/cookbook/models.py
@@ -666,6 +666,7 @@ class Supermarket(models.Model, PermissionModelMixin):
name = models.CharField(max_length=128, validators=[MinLengthValidator(1)])
description = models.TextField(blank=True, null=True)
categories = models.ManyToManyField(SupermarketCategory, through='SupermarketCategoryRelation')
+ shopping_lists = models.ManyToManyField("ShoppingList", blank=True)
open_data_slug = models.CharField(max_length=128, null=True, blank=True, default=None)
space = models.ForeignKey(Space, on_delete=models.CASCADE)
@@ -780,6 +781,7 @@ class Food(ExportModelOperationsMixin('food'), TreeModel, PermissionModelMixin):
recipe = models.ForeignKey('Recipe', null=True, blank=True, on_delete=models.SET_NULL)
url = models.CharField(max_length=1024, blank=True, null=True, default='')
supermarket_category = models.ForeignKey(SupermarketCategory, null=True, blank=True, on_delete=models.SET_NULL) # inherited field
+ shopping_lists = models.ManyToManyField("ShoppingList", blank=True)
ignore_shopping = models.BooleanField(default=False) # inherited field
onhand_users = models.ManyToManyField(User, blank=True)
description = models.TextField(default='', blank=True)
@@ -1317,6 +1319,7 @@ class ShoppingList(ExportModelOperationsMixin('shopping_list'), models.Model, Pe
class ShoppingListEntry(ExportModelOperationsMixin('shopping_list_entry'), models.Model, PermissionModelMixin):
+ shopping_lists = models.ManyToManyField(ShoppingList, blank=True)
list_recipe = models.ForeignKey(ShoppingListRecipe, on_delete=models.CASCADE, null=True, blank=True, related_name='entries')
food = models.ForeignKey(Food, on_delete=models.CASCADE, related_name='shopping_entries')
unit = models.ForeignKey(Unit, on_delete=models.SET_NULL, null=True, blank=True)
diff --git a/cookbook/serializer.py b/cookbook/serializer.py
index 9d56cf3dc..d97389c11 100644
--- a/cookbook/serializer.py
+++ b/cookbook/serializer.py
@@ -1414,6 +1414,7 @@ class ShoppingListSerializer(SpacedModelSerializer, WritableNestedModelSerialize
class ShoppingListEntrySerializer(WritableNestedModelSerializer):
food = FoodSerializer(allow_null=True)
unit = UnitSerializer(allow_null=True, required=False)
+ shopping_lists = ShoppingListSerializer(many=True, required=False)
list_recipe_data = ShoppingListRecipeSerializer(source='list_recipe', read_only=True)
amount = CustomDecimalField()
created_by = UserSerializer(read_only=True)
@@ -1482,7 +1483,7 @@ class ShoppingListEntrySerializer(WritableNestedModelSerializer):
class Meta:
model = ShoppingListEntry
fields = (
- 'id', 'list_recipe', 'food', 'unit', 'amount', 'order', 'checked', 'ingredient',
+ 'id', 'list_recipe', 'shopping_lists', 'food', 'unit', 'amount', 'order', 'checked', 'ingredient',
'list_recipe_data', 'created_by', 'created_at', 'updated_at', 'completed_at', 'delay_until', 'mealplan_id'
)
read_only_fields = ('id', 'created_by', 'created_at')
diff --git a/vue3/src/components/dialogs/ShoppingLineItemDialog.vue b/vue3/src/components/dialogs/ShoppingLineItemDialog.vue
index ad19bd3b0..3b82c3709 100644
--- a/vue3/src/components/dialogs/ShoppingLineItemDialog.vue
+++ b/vue3/src/components/dialogs/ShoppingLineItemDialog.vue
@@ -8,6 +8,9 @@
{{ $t('Choose_Category') }}
+ {{ $t('ShoppingList') }}
+
+
{{ $t('PostponedUntil') }} {{ DateTime.fromJSDate(e.delayUntil!).toLocaleString(DateTime.DATETIME_SHORT) }}
+
+ {{sl.name}}
+
@@ -122,8 +128,8 @@