unit merging
This commit is contained in:
@ -70,6 +70,23 @@ class RecipeForm(forms.Form):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UnitMergeForm(forms.Form):
|
||||||
|
prefix = 'unit'
|
||||||
|
|
||||||
|
new_unit = forms.ModelChoiceField(
|
||||||
|
queryset=Unit.objects.all(),
|
||||||
|
widget=SelectWidget,
|
||||||
|
label=_('New Unit'),
|
||||||
|
help_text=_('New unit that other gets replaced by.'),
|
||||||
|
)
|
||||||
|
old_unit = forms.ModelChoiceField(
|
||||||
|
queryset=Unit.objects.all(),
|
||||||
|
widget=SelectWidget,
|
||||||
|
label=_('Old Unit'),
|
||||||
|
help_text=_('Unit that should be replaced.'),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CommentForm(forms.ModelForm):
|
class CommentForm(forms.ModelForm):
|
||||||
prefix = 'comment'
|
prefix = 'comment'
|
||||||
|
|
||||||
|
@ -107,6 +107,9 @@
|
|||||||
class="fas fa-history"></i> {% trans 'Import Log' %}</a>
|
class="fas fa-history"></i> {% trans 'Import Log' %}</a>
|
||||||
<a class="dropdown-item" href="{% url 'data_stats' %}"><i
|
<a class="dropdown-item" href="{% url 'data_stats' %}"><i
|
||||||
class="fas fa-chart-line"></i> {% trans 'Statistics' %}</a>
|
class="fas fa-chart-line"></i> {% trans 'Statistics' %}</a>
|
||||||
|
<a class="dropdown-item" href="{% url 'edit_ingredient' %}"><i
|
||||||
|
class="fas fa-balance-scale"></i> {% trans 'Units & Ingredients' %}</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
34
cookbook/templates/forms/ingredients.html
Normal file
34
cookbook/templates/forms/ingredients.html
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% load django_tables2 %}
|
||||||
|
{% load crispy_forms_tags %}
|
||||||
|
{% load static %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "Cookbook" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block extra_head %}
|
||||||
|
{{ form.media }}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<h2><i class="fas fa-shopping-cart"></i> {% trans 'Edit Ingredients' %}</h2>
|
||||||
|
{% blocktrans %}
|
||||||
|
The following form can be used if, accidentally, two (or more) units or ingredients where created that should be
|
||||||
|
the same.
|
||||||
|
It merges two units or ingredients and updates all recipes using them.
|
||||||
|
{% endblocktrans %}
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
|
||||||
|
<h4>{% trans 'Units' %}</h4>
|
||||||
|
<form action="{% url 'edit_ingredient' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button class="btn btn-danger" type="submit"
|
||||||
|
onclick="confirm('{% trans 'Are you sure that you want to merge these two units ?' %}')"><i
|
||||||
|
class="fas fa-sync-alt"></i> {% trans 'Merge' %}</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -38,6 +38,7 @@ urlpatterns = [
|
|||||||
path('edit/comment/<int:pk>/', edit.CommentUpdate.as_view(), name='edit_comment'),
|
path('edit/comment/<int:pk>/', edit.CommentUpdate.as_view(), name='edit_comment'),
|
||||||
path('edit/recipe-book/<int:pk>/', edit.RecipeBookUpdate.as_view(), name='edit_recipe_book'),
|
path('edit/recipe-book/<int:pk>/', edit.RecipeBookUpdate.as_view(), name='edit_recipe_book'),
|
||||||
path('edit/plan/<int:pk>/', edit.MealPlanUpdate.as_view(), name='edit_plan'),
|
path('edit/plan/<int:pk>/', edit.MealPlanUpdate.as_view(), name='edit_plan'),
|
||||||
|
path('edit/ingredient/', edit.edit_ingredients, name='edit_ingredient'),
|
||||||
|
|
||||||
path('redirect/delete/<slug:name>/<int:pk>/', edit.delete_redirect, name='redirect_delete'),
|
path('redirect/delete/<slug:name>/<int:pk>/', edit.delete_redirect, name='redirect_delete'),
|
||||||
|
|
||||||
|
@ -11,10 +11,11 @@ from django.db.models import Value, CharField
|
|||||||
from django.http import HttpResponseRedirect
|
from django.http import HttpResponseRedirect
|
||||||
from django.shortcuts import redirect, get_object_or_404, render
|
from django.shortcuts import redirect, get_object_or_404, render
|
||||||
from django.urls import reverse_lazy, reverse
|
from django.urls import reverse_lazy, reverse
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _, ngettext
|
||||||
from django.views.generic import UpdateView, DeleteView
|
from django.views.generic import UpdateView, DeleteView
|
||||||
|
|
||||||
from cookbook.forms import ExternalRecipeForm, KeywordForm, StorageForm, SyncForm, InternalRecipeForm, CommentForm, MealPlanForm
|
from cookbook.forms import ExternalRecipeForm, KeywordForm, StorageForm, SyncForm, InternalRecipeForm, CommentForm, \
|
||||||
|
MealPlanForm, UnitMergeForm
|
||||||
from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage, Comment, RecipeIngredients, RecipeBook, \
|
from cookbook.models import Recipe, Sync, Keyword, RecipeImport, Storage, Comment, RecipeIngredients, RecipeBook, \
|
||||||
RecipeBookEntry, MealPlan, Unit
|
RecipeBookEntry, MealPlan, Unit
|
||||||
from cookbook.provider.dropbox import Dropbox
|
from cookbook.provider.dropbox import Dropbox
|
||||||
@ -104,7 +105,9 @@ def internal_recipe_update(request, pk):
|
|||||||
else:
|
else:
|
||||||
form = InternalRecipeForm(instance=recipe_instance)
|
form = InternalRecipeForm(instance=recipe_instance)
|
||||||
|
|
||||||
ingredients = RecipeIngredients.objects.select_related('unit__name').filter(recipe=recipe_instance).values('name', 'unit__name', 'amount')
|
ingredients = RecipeIngredients.objects.select_related('unit__name').filter(recipe=recipe_instance).values('name',
|
||||||
|
'unit__name',
|
||||||
|
'amount')
|
||||||
|
|
||||||
return render(request, 'forms/edit_internal_recipe.html',
|
return render(request, 'forms/edit_internal_recipe.html',
|
||||||
{'form': form, 'ingredients': json.dumps(list(ingredients)),
|
{'form': form, 'ingredients': json.dumps(list(ingredients)),
|
||||||
@ -290,8 +293,29 @@ class RecipeUpdate(LoginRequiredMixin, UpdateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
|
|
||||||
# Generic Delete views
|
@login_required
|
||||||
|
def edit_ingredients(request):
|
||||||
|
if request.method == "POST":
|
||||||
|
form = UnitMergeForm(request.POST, prefix=UnitMergeForm.prefix)
|
||||||
|
if form.is_valid():
|
||||||
|
new_unit = form.cleaned_data['new_unit']
|
||||||
|
old_unit = form.cleaned_data['old_unit']
|
||||||
|
ingredients = RecipeIngredients.objects.filter(unit=old_unit).all()
|
||||||
|
for i in ingredients:
|
||||||
|
i.unit = new_unit
|
||||||
|
i.save()
|
||||||
|
|
||||||
|
old_unit.delete()
|
||||||
|
messages.add_message(request, messages.SUCCESS, _('Units merged!'))
|
||||||
|
else:
|
||||||
|
messages.add_message(request, messages.WARNING, _('There was an error in your form.'))
|
||||||
|
else:
|
||||||
|
form = UnitMergeForm()
|
||||||
|
|
||||||
|
return render(request, 'forms/ingredients.html', {'form': form})
|
||||||
|
|
||||||
|
|
||||||
|
# Generic Delete views
|
||||||
def delete_redirect(request, name, pk):
|
def delete_redirect(request, name, pk):
|
||||||
return redirect(('delete_' + name), pk)
|
return redirect(('delete_' + name), pk)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user