basic shopping view
This commit is contained in:
parent
6a61c934cd
commit
227d90d49d
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||||
|
</state>
|
||||||
|
</component>
|
@ -1,3 +1,4 @@
|
|||||||
|
from dal import autocomplete
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.forms import widgets
|
from django.forms import widgets
|
||||||
from django.utils.translation import gettext as _
|
from django.utils.translation import gettext as _
|
||||||
@ -60,6 +61,13 @@ class InternalRecipeForm(forms.ModelForm):
|
|||||||
widgets = {'keywords': MultiSelectWidget}
|
widgets = {'keywords': MultiSelectWidget}
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeForm(forms.Form):
|
||||||
|
recipe = forms.ModelMultipleChoiceField(
|
||||||
|
queryset=Recipe.objects.all(),
|
||||||
|
widget=MultiSelectWidget
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class CommentForm(forms.ModelForm):
|
class CommentForm(forms.ModelForm):
|
||||||
prefix = 'comment'
|
prefix = 'comment'
|
||||||
|
|
||||||
|
@ -81,6 +81,9 @@ class RecipeIngredients(models.Model):
|
|||||||
unit = models.CharField(max_length=128)
|
unit = models.CharField(max_length=128)
|
||||||
amount = models.DecimalField(default=0, decimal_places=2, max_digits=16)
|
amount = models.DecimalField(default=0, decimal_places=2, max_digits=16)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.amount) + ' ' + self.unit + ' ' + self.name
|
||||||
|
|
||||||
|
|
||||||
class Comment(models.Model):
|
class Comment(models.Model):
|
||||||
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
|
recipe = models.ForeignKey(Recipe, on_delete=models.CASCADE)
|
||||||
@ -89,6 +92,9 @@ class Comment(models.Model):
|
|||||||
created_at = models.DateTimeField(auto_now_add=True)
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
updated_at = models.DateTimeField(auto_now=True)
|
updated_at = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.text
|
||||||
|
|
||||||
|
|
||||||
class RecipeImport(models.Model):
|
class RecipeImport(models.Model):
|
||||||
name = models.CharField(max_length=128)
|
name = models.CharField(max_length=128)
|
||||||
|
@ -73,10 +73,12 @@
|
|||||||
class="sr-only">(current)</span></a>
|
class="sr-only">(current)</span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{% url 'view_books' %}"><i class="fas fa-bookmark"></i> {% trans 'Books' %}</a>
|
<a class="nav-link" href="{% url 'view_books' %}"><i class="fas fa-bookmark"></i> {% trans 'Books' %}
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link" href="{% url 'view_plan' %}"><i class="fas fa-calendar"></i> {% trans 'Meal-Plan' %}</a>
|
<a class="nav-link" href="{% url 'view_plan' %}"><i class="fas fa-calendar"></i> {% trans 'Meal-Plan' %}
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown">
|
<li class="nav-item dropdown">
|
||||||
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown"
|
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdownMenuLink" data-toggle="dropdown"
|
||||||
|
44
cookbook/templates/shopping_list.html
Normal file
44
cookbook/templates/shopping_list.html
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
{% 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 'Shopping List' %}</h2>
|
||||||
|
|
||||||
|
<form action="{% url 'view_shopping' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|crispy }}
|
||||||
|
<button class="btn btn-success" type="submit"><i class="fas fa-sync-alt"></i> {% trans 'Load' %}</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<br/>
|
||||||
|
<br/>
|
||||||
|
<button class="btn btn-success" onclick="copy()"><i class="far fa-copy"></i></button>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-md-12">
|
||||||
|
<!--// @formatter:off-->
|
||||||
|
<textarea id="id_list" style="height: 50vh" class="form-control">{% for i in ingredients %}- [ ] {{ i.amount.normalize }} {{ i.unit }} {{ i.name }} {% endfor %}</textarea>
|
||||||
|
<!--// @formatter:on-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
function copy() {
|
||||||
|
let list = $('#id_list');
|
||||||
|
|
||||||
|
list.select();
|
||||||
|
|
||||||
|
document.execCommand("copy");
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -6,8 +6,9 @@ from cookbook.helper import dal
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.index, name='index'),
|
path('', views.index, name='index'),
|
||||||
path('books', views.books, name='view_books'),
|
path('books/', views.books, name='view_books'),
|
||||||
path('plan', views.meal_plan, name='view_plan'),
|
path('plan/', views.meal_plan, name='view_plan'),
|
||||||
|
path('shopping/', views.shopping_list, name='view_shopping'),
|
||||||
|
|
||||||
path('view/recipe/<int:pk>', views.recipe_view, name='view_recipe'),
|
path('view/recipe/<int:pk>', views.recipe_view, name='view_recipe'),
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import copy
|
import copy
|
||||||
|
import re
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
@ -112,3 +113,31 @@ def meal_plan(request):
|
|||||||
plan[p.meal]['days'][d].append(p)
|
plan[p.meal]['days'][d].append(p)
|
||||||
|
|
||||||
return render(request, 'meal_plan.html', {'js_week': js_week, 'plan': plan, 'days': days, 'surrounding_weeks': surrounding_weeks})
|
return render(request, 'meal_plan.html', {'js_week': js_week, 'plan': plan, 'days': days, 'surrounding_weeks': surrounding_weeks})
|
||||||
|
|
||||||
|
|
||||||
|
@login_required
|
||||||
|
def shopping_list(request):
|
||||||
|
if request.method == "POST":
|
||||||
|
form = RecipeForm(request.POST)
|
||||||
|
if form.is_valid():
|
||||||
|
recipes = form.cleaned_data['recipe']
|
||||||
|
else:
|
||||||
|
recipes = []
|
||||||
|
else:
|
||||||
|
raw_list = request.GET.getlist('r')
|
||||||
|
|
||||||
|
recipes = []
|
||||||
|
for r in raw_list:
|
||||||
|
if re.match(r'^([1-9])+$', r):
|
||||||
|
if Recipe.objects.filter(pk=int(r)).exists():
|
||||||
|
recipes.append(int(r))
|
||||||
|
|
||||||
|
form = RecipeForm(initial={'recipe': recipes})
|
||||||
|
|
||||||
|
ingredients = []
|
||||||
|
|
||||||
|
for r in recipes:
|
||||||
|
for i in RecipeIngredients.objects.filter(recipe=r).all():
|
||||||
|
ingredients.append(i)
|
||||||
|
|
||||||
|
return render(request, 'shopping_list.html', {'ingredients': ingredients, 'recipes': recipes, 'form': form})
|
||||||
|
Loading…
Reference in New Issue
Block a user