TandoorRecipes / recipes

Application for managing recipes, planning meals, building shopping lists and much much more!
https://docs.tandoor.dev
Other
5.34k stars 563 forks source link

Error when deleting a food resource #1528

Closed mhoenes closed 2 years ago

mhoenes commented 2 years ago

Tandoor Version

1.0.8

Setup

Docker / Docker-Compose

Reverse Proxy

SWAG

Other

No response

Bug description

Some foods cannot be deleted although they are not referenced in any recipe. The failure message says "There was an error deleting a resource!".

Some foods can be deleted just fine, while others constantly produce this error. A log example is attached.

Relevant logs

Forbidden: /api/food/344/
172.18.0.1 - - [13/Feb/2022:16:23:27 +0100] "DELETE /api/food/344/ HTTP/1.1" 403 92 "https://xxxxxxxxxxx/list/food/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.82 Safari/537.36"
smilerz commented 2 years ago

Can you please enable DEBUG in .env and reshare the logs

mhoenes commented 2 years ago

DEBUG already has been enabled, but what I posted is all that can be found in the logs.

smilerz commented 2 years ago

Can you go to the details of that food (344) in Admin and provide the details on that screen.

mhoenes commented 2 years ago

This is a screenshot of a food which has the same issue (different id though) image

mhoenes commented 2 years ago

Looks like the issue is caused by 3 step-ingredient records, where this food is referenced. However the steps are orphans, they are not linked to any recipe. I remember running into errors when importing my recipes from another tool. Maybe this caused the orphaned records. image

mhoenes commented 2 years ago

Yup, deleting from Admin produces a proper stack trace and confirms that the step-ingredients are the cause: Environment:

Request Method: POST Request URL: https://xxxxxxxx/admin/cookbook/food/325/delete/

Django Version: 3.2.11 Python Version: 3.9.5 Installed Applications: ['dal', 'dal_select2', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.sites', 'django.contrib.staticfiles', 'django.contrib.postgres', 'django_prometheus', 'django_tables2', 'corsheaders', 'django_filters', 'crispy_forms', 'rest_framework', 'rest_framework.authtoken', 'django_cleanup.apps.CleanupConfig', 'webpack_loader', 'django_js_reverse', 'hcaptcha', 'allauth', 'allauth.account', 'allauth.socialaccount', 'cookbook.apps.CookbookConfig', 'treebeard'] Installed Middleware: ['corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'whitenoise.middleware.WhiteNoiseMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.locale.LocaleMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'cookbook.helper.scope_middleware.ScopeMiddleware']

Traceback (most recent call last): File "/opt/recipes/venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "/opt/recipes/venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response response = wrapped_callback(request, *callback_args, callback_kwargs) File "/opt/recipes/venv/lib/python3.9/site-packages/django/contrib/admin/options.py", line 616, in wrapper return self.admin_site.admin_view(view)(*args, *kwargs) File "/opt/recipes/venv/lib/python3.9/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, args, kwargs) File "/opt/recipes/venv/lib/python3.9/site-packages/django/views/decorators/cache.py", line 44, in _wrapped_view_func response = view_func(request, *args, kwargs) File "/opt/recipes/venv/lib/python3.9/site-packages/django/contrib/admin/sites.py", line 232, in inner return view(request, *args, *kwargs) File "/opt/recipes/venv/lib/python3.9/site-packages/django/utils/decorators.py", line 43, in _wrapper return bound_method(args, kwargs) File "/opt/recipes/venv/lib/python3.9/site-packages/django/utils/decorators.py", line 130, in _wrapped_view response = view_func(request, *args, **kwargs) File "/opt/recipes/venv/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1851, in delete_view return self._delete_view(request, object_id, extra_context) File "/opt/recipes/venv/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1881, in _delete_view self.delete_model(request, obj) File "/opt/recipes/venv/lib/python3.9/site-packages/django/contrib/admin/options.py", line 1105, in deletemodel obj.delete() File "/opt/recipes/cookbook/models.py", line 513, in delete raise ProtectedError(self.name + (" is part of a recipe step and cannot be deleted"), self.ingredient_set.all().exclude(step=None))

Exception Type: ProtectedError at /admin/cookbook/food/325/delete/ Exception Value: ('oder sizilianische Biozitrone is part of a recipe step and cannot be deleted', <QuerySet [<Ingredient: 2.0000000000000000 Amalfi-Zitronen oder sizilianische Biozitrone>]>)

smilerz commented 2 years ago

@mhoenes that sounds correct - there are a couple work arounds.

  1. you can delete the steps and ingredients in the Admin (find via the ID number in your screenshot)
  2. merge the food you want to delete with another food. The merged food would have the orphaned steps still attached, but you would have gotten rid of the food you don't want to see.
mhoenes commented 2 years ago

@smilerz : I ended up deleting orphaned steps and ingredients directly on the DB. There have been too many to correct them manually. I guess there is a defect in the import from Recipekeeper. I ran the import multiple times a few months back and thid most likely lead to all those orphan records.

vabene1111 commented 2 years ago

we need to add some management tools to the "system" page to delete orphans and stuff until the step, thats been something i wanted to do for a long time ..