From abbba03debb9f752602fd523b27c56677503f2f2 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Sat, 11 Mar 2023 19:18:24 +0100 Subject: [PATCH] Add views --- recipes/views.py | 149 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 2 deletions(-) diff --git a/recipes/views.py b/recipes/views.py index 91ea44a..032dd20 100644 --- a/recipes/views.py +++ b/recipes/views.py @@ -1,3 +1,148 @@ -from django.shortcuts import render +from django.shortcuts import render, get_object_or_404, redirect +from .models import Recipe, Version, Ingredient +from .forms import RecipeForm, VersionForm, IngredientFormSet +from django.contrib.auth.decorators import login_required +from django.urls import reverse +from django.http.response import HttpResponseRedirect +from django.conf import settings -# Create your views here. +RECIPE_FORM_PREFIX = 'recipe' +VERSION_FORM_PREFIX = 'version' +INGREDIENTS_FORMSET_PREFIX = 'ingredient' + +def get_name_of_user(user): + return user.first_name if user.first_name else user.username + +@login_required +def recipes(request): + recipes = Recipe.objects.all() + return render(request, 'recipes.html', context={'recipes': recipes}) + +def version(request, slug_recipe, slug_version): + recipe = get_object_or_404(Recipe, slug=slug_recipe) + has_multiple_versions = recipe.versions.all().count() > 1 # type: ignore + version = get_object_or_404(Version, recipe=recipe, slug=slug_version) + ingredients = version.ingredients.all() # type: ignore + + return render(request, 'version.html', context={'recipe': recipe, 'has_multiple_versions': has_multiple_versions, 'version': version, 'ingredients': ingredients}) + +@login_required +def recipe(request, slug): + recipe = get_object_or_404(Recipe, slug=slug) + versions = recipe.versions.all() # type: ignore + + if (1 == versions.count()): + return HttpResponseRedirect(reverse('version', kwargs={'slug_recipe': slug, 'slug_version': versions.get().slug})) + else: + return render(request, 'recipe.html', context={'recipe': recipe, 'versions': versions}) + +def create_version(request, recipe: Recipe, version_form: VersionForm) -> Version: + version = version_form.save(commit=False) + version.user = request.user + version.recipe = recipe + version.save() + return version + +def save_ingredients(version: Version, ingredients_formset: IngredientFormSet): # type: ignore + for ingredient in ingredients_formset.save(commit=False): + ingredient.version = version + ingredient.save() + +@login_required +def add_recipe(request): + if request.method == 'POST': + recipe_form = RecipeForm(request.POST, prefix=RECIPE_FORM_PREFIX) + version_form = VersionForm(request.POST, prefix=VERSION_FORM_PREFIX, author_placeholder=get_name_of_user(request.user)) + ingredients_formset = IngredientFormSet(request.POST, queryset=Ingredient.objects.none(), prefix=INGREDIENTS_FORMSET_PREFIX) + + if recipe_form.is_valid() and version_form.is_valid() and ingredients_formset.is_valid(): + recipe = recipe_form.save(commit=True) + version = create_version(request, recipe, version_form) + save_ingredients(version, ingredients_formset) + + return HttpResponseRedirect(reverse('recipe', kwargs={'slug': recipe.slug})) + else: + recipe_form = RecipeForm(prefix=RECIPE_FORM_PREFIX) + version_form = VersionForm(prefix=VERSION_FORM_PREFIX, author_placeholder=get_name_of_user(request.user)) + ingredients_formset = IngredientFormSet(queryset=Ingredient.objects.none(), prefix=INGREDIENTS_FORMSET_PREFIX) + + return render(request, 'add-recipe.html', {'recipe_form': recipe_form, 'version_form': version_form, 'ingredients_formset': ingredients_formset}) + +@login_required +def edit_recipe(request, slug): + recipe = get_object_or_404(Recipe, slug=slug) + + # It is assumed every recipe has at least one version + if not request.user.is_superuser: + users = set() + + for version in recipe.versions.all(): # type: ignore + users.add(version.user) + + if len(users) > 1 or (len(users) == 1 and next(iter(users)) != request.user): + return redirect(f"/accounts/login/?next={request.path}") + + if request.method == 'POST': + form = RecipeForm(request.POST, instance=recipe, prefix=RECIPE_FORM_PREFIX) + if form.is_valid(): + if form.has_changed(): + form.save() + return HttpResponseRedirect(reverse('recipe', kwargs={'slug': recipe.slug})) + else: + form = RecipeForm(instance=recipe, prefix=RECIPE_FORM_PREFIX) + + return render(request, 'edit-recipe.html', {'form': form}) + +@login_required +def add_version(request, slug): + recipe = get_object_or_404(Recipe, slug=slug) + if (recipe.versions.all().count() > 0): # type: ignore + version_initial = {'label': '', 'slug': ''} + else: + version_initial = {} + + if request.method == 'POST': + version_form = VersionForm(request.POST, prefix=VERSION_FORM_PREFIX, initial=version_initial, author_placeholder=get_name_of_user(request.user)) + ingredients_formset = IngredientFormSet(request.POST, queryset=Ingredient.objects.none(), prefix=INGREDIENTS_FORMSET_PREFIX) + version_form.recipe_id = recipe.id # type: ignore + + if version_form.is_valid() and ingredients_formset.is_valid(): + version = create_version(request, recipe, version_form) + save_ingredients(version, ingredients_formset) + + return HttpResponseRedirect(reverse('version', kwargs={'slug_recipe': version.recipe.slug, 'slug_version': version.slug})) + + else: + version_form = VersionForm(prefix=VERSION_FORM_PREFIX, initial=version_initial, author_placeholder=get_name_of_user(request.user)) + ingredients_formset = IngredientFormSet(queryset=Ingredient.objects.none(), prefix=INGREDIENTS_FORMSET_PREFIX) + + return render(request, 'add-version.html', {'version_form': version_form, 'ingredients_formset': ingredients_formset}) + +@login_required +def edit_version(request, slug_recipe, slug_version): + recipe = get_object_or_404(Recipe, slug=slug_recipe) + version = get_object_or_404(Version, recipe=recipe, slug=slug_version) + + if version.user != request.user and not request.user.is_superuser: + return redirect(f"/accounts/login/?next={request.path}") + + if request.method == 'POST': + version_form = VersionForm(request.POST, prefix=VERSION_FORM_PREFIX, instance=version, author_placeholder=get_name_of_user(request.user)) + ingredients_formset = IngredientFormSet(request.POST, queryset=version.ingredients.all(), prefix=INGREDIENTS_FORMSET_PREFIX) # type: ignore + version_form.recipe_id = recipe.id # type: ignore + + if version_form.is_valid() and ingredients_formset.is_valid(): + if version_form.has_changed(): + version = version_form.save() + + if ingredients_formset.has_changed(): + for ingredient in ingredients_formset.save(commit=False): + ingredient.version = version + ingredient.save() + + return HttpResponseRedirect(reverse('version', kwargs={'slug_recipe': version.recipe.slug, 'slug_version': version.slug})) + else: + version_form = VersionForm(instance=version, prefix=VERSION_FORM_PREFIX, author_placeholder=get_name_of_user(request.user)) + ingredients_formset = IngredientFormSet(queryset=version.ingredients.all(), prefix=INGREDIENTS_FORMSET_PREFIX) # type: ignore + + return render(request, 'edit-version.html', {'version_form': version_form, 'ingredients_formset': ingredients_formset})