mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2025-12-30 21:49:50 -05:00
Merge pull request #58 from tourn/recipe-serving-count
Add serving count to recipe
This commit is contained in:
@@ -88,13 +88,14 @@ class InternalRecipeForm(forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
model = Recipe
|
||||
fields = ('name', 'image', 'working_time', 'waiting_time', 'keywords')
|
||||
fields = ('name', 'image', 'working_time', 'waiting_time', 'servings', 'keywords')
|
||||
|
||||
labels = {
|
||||
'name': _('Name'),
|
||||
'keywords': _('Keywords'),
|
||||
'working_time': _('Preparation time in minutes'),
|
||||
'waiting_time': _('Waiting time (cooking/baking) in minutes'),
|
||||
'servings': _('Number of servings'),
|
||||
}
|
||||
widgets = {'keywords': MultiSelectWidget}
|
||||
|
||||
|
||||
18
cookbook/migrations/0091_recipe_servings.py
Normal file
18
cookbook/migrations/0091_recipe_servings.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 3.0.7 on 2020-08-30 13:32
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cookbook', '0090_auto_20201214_1359'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='recipe',
|
||||
name='servings',
|
||||
field=models.IntegerField(default=1),
|
||||
),
|
||||
]
|
||||
@@ -197,6 +197,7 @@ class NutritionInformation(models.Model):
|
||||
|
||||
class Recipe(models.Model):
|
||||
name = models.CharField(max_length=128)
|
||||
servings = models.IntegerField(default=1)
|
||||
image = models.ImageField(upload_to='recipes/', blank=True, null=True)
|
||||
storage = models.ForeignKey(Storage, on_delete=models.PROTECT, blank=True, null=True)
|
||||
file_uid = models.CharField(max_length=256, default="", blank=True)
|
||||
|
||||
@@ -153,7 +153,7 @@ class RecipeSerializer(WritableNestedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = Recipe
|
||||
fields = ['id', 'name', 'image', 'keywords', 'steps', 'working_time', 'waiting_time', 'created_by', 'created_at', 'updated_at', 'internal', 'nutrition']
|
||||
fields = ['id', 'name', 'image', 'keywords', 'steps', 'working_time', 'waiting_time', 'created_by', 'created_at', 'updated_at', 'internal', 'nutrition', 'servings']
|
||||
read_only_fields = ['image', 'created_by', 'created_at']
|
||||
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@
|
||||
<label for="id_name"> {% trans 'Waiting Time' %}</label>
|
||||
<input class="form-control" id="id_wait_time" v-model="recipe.waiting_time">
|
||||
<br/>
|
||||
<label for="id_name"> {% trans 'Servings' %}</label>
|
||||
<input class="form-control" id="id_servings" v-model="recipe.servings">
|
||||
<br/>
|
||||
<label for="id_name"> {% trans 'Keywords' %}</label>
|
||||
<multiselect
|
||||
v-model="recipe.keywords"
|
||||
|
||||
@@ -122,8 +122,11 @@
|
||||
</div>
|
||||
<draggable class="list-group" :list="recipes"
|
||||
:group="{ name: 'plan', pull: 'clone', put: false }" :clone="cloneRecipe">
|
||||
<div class="list-group-item" v-for="(element, index) in recipes" :key="element.id">
|
||||
<i class="fas fa-arrows-alt"></i> [[element.name]]
|
||||
<div class="list-group-item d-flex align-items-center justify-content-between" v-for="(element, index) in recipes" :key="element.id">
|
||||
<span>
|
||||
<i class="fas fa-arrows-alt"></i> [[element.name]]
|
||||
</span>
|
||||
<span class="badge badge-light badge-pill">[[element.servings]]</span>
|
||||
</div>
|
||||
</draggable>
|
||||
</div>
|
||||
@@ -140,7 +143,7 @@
|
||||
<br/>
|
||||
<br/>
|
||||
<input type="number" class="form-control" v-model="new_note_multiplier"
|
||||
placeholder="{% trans 'Recipe Multiplier' %}" style="margin-bottom: 8px">
|
||||
placeholder="{% trans 'Serving Count' %}" style="margin-bottom: 8px">
|
||||
<br/>
|
||||
<draggable :list="pseudo_note_list"
|
||||
:group="{ name: 'plan', pull: 'clone', put: false }" :clone="cloneNote">
|
||||
@@ -243,6 +246,9 @@
|
||||
<small class="text-muted">{% trans 'Recipe' %}</small><br/>
|
||||
<a v-bind:href="planDetailRecipeUrl()" target="_blank">[[ plan_detail.recipe_name ]]</a>
|
||||
<br/>
|
||||
<br/>
|
||||
<small class="text-muted">{% trans 'Serving Count' %}</small><br/>
|
||||
<span>[[ plan_detail.recipe_multiplier ]]</span>
|
||||
</template>
|
||||
|
||||
<template v-if="plan_detail.note !== ''">
|
||||
@@ -615,7 +621,7 @@
|
||||
id: Math.round(Math.random() * 1000) + 10000,
|
||||
recipe: recipe.id,
|
||||
recipe_name: recipe.name,
|
||||
recipe_multiplier: (this.new_note_multiplier > 1) ? this.new_note_multiplier : 1,
|
||||
recipe_multiplier: (this.new_note_multiplier > 1) ? this.new_note_multiplier : recipe.servings,
|
||||
title: this.new_note_title,
|
||||
note: this.new_note_text,
|
||||
is_new: true
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
<button class="dropdown-item" onclick="$('#bookmarkModal').modal({'show':true})">
|
||||
<i class="fas fa-bookmark fa-fw"></i> {% trans 'Add to Book' %}</button>
|
||||
|
||||
<a class="dropdown-item" v-bind:href="getShoppingUrl()" v-if="has_ingredients">
|
||||
<a class="dropdown-item" v-bind:href="shopping_url" v-if="has_ingredients">
|
||||
<i class="fas fa-shopping-cart fa-fw"></i> {% trans 'Add to Shopping' %}</a>
|
||||
|
||||
<a class="dropdown-item" href="{% url 'new_meal_plan' %}?recipe={{ recipe.pk }}"><i
|
||||
@@ -109,8 +109,8 @@
|
||||
<div class="col col-md-3">
|
||||
|
||||
<div class="input-group d-print-none">
|
||||
<input type="number" value="1" min="1" max="999" class="form-control"
|
||||
v-model="ingredient_factor"/>
|
||||
<input type="number" value="1" maxlength="3" class="form-control"
|
||||
v-model="servings"/>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text"><i class="fas fa-calculator"></i></span>
|
||||
</div>
|
||||
@@ -516,6 +516,8 @@
|
||||
let csrftoken = Cookies.get('csrftoken');
|
||||
Vue.http.headers.common['X-CSRFToken'] = csrftoken;
|
||||
|
||||
const recipe_servings = {{ recipe.servings }}
|
||||
|
||||
let app = new Vue({
|
||||
delimiters: ['[[', ']]'],
|
||||
el: '#id_base_container',
|
||||
@@ -523,9 +525,16 @@
|
||||
recipe: undefined,
|
||||
has_ingredients: false,
|
||||
has_times: false,
|
||||
ingredient_factor: 1,
|
||||
servings: recipe_servings,
|
||||
},
|
||||
computed: {
|
||||
ingredient_factor: function () {
|
||||
return this.servings / recipe_servings
|
||||
},
|
||||
shopping_url: function () {
|
||||
return `{% url 'view_shopping' %}?r=[${this.recipe.id},${this.servings}]`
|
||||
},
|
||||
},
|
||||
|
||||
mounted: function () {
|
||||
this.loadRecipe()
|
||||
},
|
||||
@@ -577,9 +586,6 @@
|
||||
}
|
||||
|
||||
},
|
||||
getShoppingUrl: function () {
|
||||
return `{% url 'view_shopping' %}?r=[${this.recipe.id},${this.ingredient_factor}]`
|
||||
},
|
||||
calculateAmount: function (amount) {
|
||||
{% if request.user.userpreference.use_fractions %}
|
||||
let return_string = ''
|
||||
|
||||
@@ -349,7 +349,12 @@
|
||||
multiplier_cache() {
|
||||
let cache = {}
|
||||
this.shopping_list.recipes.forEach((r) => {
|
||||
cache[r.id] = !(Number.isNaN(r.multiplier)) ? parseFloat(r.multiplier) : 1
|
||||
let multiplier = r.servings;
|
||||
if(!Number.isNaN(r.multiplier)){
|
||||
multiplier = parseFloat(r.multiplier)
|
||||
}
|
||||
cache[r.id] = multiplier / r.servings;
|
||||
|
||||
})
|
||||
return cache
|
||||
},
|
||||
@@ -621,7 +626,8 @@
|
||||
"id": Math.random() * 1000,
|
||||
"recipe": recipe.id,
|
||||
"recipe_name": recipe.name,
|
||||
"multiplier": multiplier
|
||||
"multiplier": multiplier,
|
||||
"servings": recipe.servings,
|
||||
}
|
||||
|
||||
this.shopping_list.recipes.push(slr)
|
||||
|
||||
Reference in New Issue
Block a user