From 805575445589f7af3641b8d28e8fc4cc9d224e5d Mon Sep 17 00:00:00 2001 From: vabene1111 Date: Tue, 11 Aug 2020 12:17:12 +0200 Subject: [PATCH] shopping list basics --- ...st_shoppinglistentry_shoppinglistrecipe.py | 49 ++++++++++++++++++ cookbook/models.py | 23 +++++++++ cookbook/tables.py | 9 ++++ cookbook/templates/base.html | 2 +- cookbook/templates/shopping_list.html | 51 +------------------ cookbook/urls.py | 2 +- cookbook/views/lists.py | 12 ++++- 7 files changed, 95 insertions(+), 53 deletions(-) create mode 100644 cookbook/migrations/0075_shoppinglist_shoppinglistentry_shoppinglistrecipe.py diff --git a/cookbook/migrations/0075_shoppinglist_shoppinglistentry_shoppinglistrecipe.py b/cookbook/migrations/0075_shoppinglist_shoppinglistentry_shoppinglistrecipe.py new file mode 100644 index 000000000..c5e01f586 --- /dev/null +++ b/cookbook/migrations/0075_shoppinglist_shoppinglistentry_shoppinglistrecipe.py @@ -0,0 +1,49 @@ +# Generated by Django 3.0.7 on 2020-08-11 10:14 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion +import uuid + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('cookbook', '0074_remove_keyword_created_by'), + ] + + operations = [ + migrations.CreateModel( + name='ShoppingListRecipe', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('multiplier', models.IntegerField(default=1)), + ('recipe', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.Recipe')), + ], + ), + migrations.CreateModel( + name='ShoppingListEntry', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('amount', models.IntegerField(default=1)), + ('order', models.IntegerField(default=0)), + ('checked', models.BooleanField(default=False)), + ('food', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.Food')), + ('list_recipe', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.ShoppingListRecipe')), + ('unit', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.Unit')), + ], + ), + migrations.CreateModel( + name='ShoppingList', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('uuid', models.UUIDField(default=uuid.uuid4)), + ('note', models.TextField(blank=True, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), + ('recipes', models.ManyToManyField(blank=True, to='cookbook.ShoppingListRecipe')), + ('shared', models.ManyToManyField(blank=True, related_name='list_share', to=settings.AUTH_USER_MODEL)), + ], + ), + ] diff --git a/cookbook/models.py b/cookbook/models.py index a6a2d8629..20dfd7e39 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -265,6 +265,29 @@ class MealPlan(models.Model): return f'{self.get_label()} - {self.date} - {self.meal_type.name}' +class ShoppingListRecipe(models.Model): + recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE, null=True, blank=True) + multiplier = models.IntegerField(default=1) + + +class ShoppingListEntry(models.Model): + list_recipe = models.ForeignKey(ShoppingListRecipe, on_delete=models.CASCADE, null=True, blank=True) + food = models.ForeignKey(Food, on_delete=models.CASCADE) + unit = models.ForeignKey(Unit, on_delete=models.CASCADE, null=True, blank=True) + amount = models.IntegerField(default=1) + order = models.IntegerField(default=0) + checked = models.BooleanField(default=False) + + +class ShoppingList(models.Model): + uuid = models.UUIDField(default=uuid.uuid4) + note = models.TextField(blank=True, null=True) + recipes = models.ManyToManyField(ShoppingListRecipe, blank=True) + shared = models.ManyToManyField(User, blank=True, related_name='list_share') + created_by = models.ForeignKey(User, on_delete=models.CASCADE) + created_at = models.DateTimeField(auto_now_add=True) + + class ShareLink(models.Model): recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE) uuid = models.UUIDField(default=uuid.uuid4) diff --git a/cookbook/tables.py b/cookbook/tables.py index 30c9c67c2..0d04010ab 100644 --- a/cookbook/tables.py +++ b/cookbook/tables.py @@ -108,6 +108,15 @@ class RecipeImportTable(tables.Table): fields = ('id', 'name', 'file_path') +class ShoppingListTable(tables.Table): + id = tables.LinkColumn('edit_storage', args=[A('id')]) + + class Meta: + model = ShoppingList + template_name = 'generic/table_template.html' + fields = ('id', 'created_by', 'created_at') + + class ViewLogTable(tables.Table): recipe = tables.LinkColumn('view_recipe', args=[A('recipe_id')]) diff --git a/cookbook/templates/base.html b/cookbook/templates/base.html index 8f5980371..f2977df67 100644 --- a/cookbook/templates/base.html +++ b/cookbook/templates/base.html @@ -72,7 +72,7 @@ {% trans 'Meal-Plan' %} - {% trans 'Shopping' %} {% trans 'Shopping List' %} -
- {% csrf_token %} - {{ form|crispy }} - -
- -
-
- -
-
- - - -
-
-
-
-
- -
-
- - {% endblock %} \ No newline at end of file diff --git a/cookbook/urls.py b/cookbook/urls.py index 13c29c279..b4e29d8f1 100644 --- a/cookbook/urls.py +++ b/cookbook/urls.py @@ -89,7 +89,7 @@ urlpatterns = [ ] -generic_models = (Recipe, RecipeImport, Storage, RecipeBook, MealPlan, SyncLog, Sync, Comment, RecipeBookEntry, Keyword, Food) +generic_models = (Recipe, RecipeImport, Storage, RecipeBook, MealPlan, SyncLog, Sync, Comment, RecipeBookEntry, Keyword, Food, ShoppingList) for m in generic_models: py_name = get_model_name(m) diff --git a/cookbook/views/lists.py b/cookbook/views/lists.py index 6ebb2fda4..2869fad67 100644 --- a/cookbook/views/lists.py +++ b/cookbook/views/lists.py @@ -6,8 +6,8 @@ from django_tables2 import RequestConfig from cookbook.filters import IngredientFilter from cookbook.helper.permission_helper import group_required -from cookbook.models import Keyword, SyncLog, RecipeImport, Storage, Food -from cookbook.tables import KeywordTable, ImportLogTable, RecipeImportTable, StorageTable, IngredientTable +from cookbook.models import Keyword, SyncLog, RecipeImport, Storage, Food, ShoppingList +from cookbook.tables import KeywordTable, ImportLogTable, RecipeImportTable, StorageTable, IngredientTable, ShoppingListTable @group_required('user') @@ -45,6 +45,14 @@ def food(request): return render(request, 'generic/list_template.html', {'title': _("Ingredients"), 'table': table, 'filter': f}) +@group_required('user') +def shopping_list(request): + table = ShoppingListTable(ShoppingList.objects.filter(created_by=request.user).all()) + RequestConfig(request, paginate={'per_page': 25}).configure(table) + + return render(request, 'generic/list_template.html', {'title': _("Shopping Lists"), 'table': table, 'create_url': 'new_storage'}) + + @group_required('admin') def storage(request): table = StorageTable(Storage.objects.all())