generated from 2martens/django-template
Created models for food planner
This commit is contained in:
@ -41,4 +41,5 @@ class UserForm(forms.ModelForm):
|
|||||||
class ProfileForm(forms.ModelForm):
|
class ProfileForm(forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Profile
|
model = Profile
|
||||||
|
fields = ['daily_fat_demand', 'daily_carbohydrate_demand',
|
||||||
|
'daily_sugar_demand', 'daily_roughage_demand', 'daily_protein_demand']
|
||||||
|
|||||||
145
food_planner/migrations/0001_initial.py
Normal file
145
food_planner/migrations/0001_initial.py
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
# Generated by Django 3.0.3 on 2020-02-19 11:35
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Ingredient',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='Name')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='KitchenUtility',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='Name')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Pantry',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Recipe',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='Name')),
|
||||||
|
('image', models.ImageField(blank=True, null=True, upload_to='', verbose_name='Image')),
|
||||||
|
('experience_level', models.CharField(choices=[('NOV', 'Novice'), ('INT', 'Intermediate'), ('ADV', 'Advanced'), ('EXP', 'Expert')], max_length=255, verbose_name='Required cooking experience')),
|
||||||
|
('fat', models.PositiveIntegerField(help_text='How much fat does one portion contain?', verbose_name='Fat')),
|
||||||
|
('carbohydrates', models.PositiveIntegerField(help_text='How much carbohydrates does one portion contain?', verbose_name='Carbohydrates')),
|
||||||
|
('sugar', models.PositiveIntegerField(help_text='How much sugar does one portion contain?', verbose_name='Sugar')),
|
||||||
|
('roughage', models.PositiveIntegerField(help_text='How much roughage does one portion contain?', verbose_name='Roughage')),
|
||||||
|
('protein', models.PositiveIntegerField(help_text='How much protein does one portion contain?', verbose_name='Protein')),
|
||||||
|
('author', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Vendor',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=50, verbose_name='Vendor')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UsedKitchenUtilities',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('amount', models.PositiveIntegerField(default=1, help_text='How often is this kitchen utility used?', verbose_name='Amount')),
|
||||||
|
('kitchen_utility', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='food_planner.KitchenUtility')),
|
||||||
|
('recipe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='food_planner.Recipe')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UsedIngredients',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('amount', models.PositiveIntegerField(help_text='Please specify the used amount of the ingredient', verbose_name='Amount')),
|
||||||
|
('unit', models.CharField(choices=[('KG', 'kg'), ('G', 'g'), ('MG', 'mg'), ('L', 'l'), ('ML', 'ml'), ('TEA', 'teaspoon'), ('TBL', 'tablespoon'), ('PINCH', 'pinch'), ('PIECE', 'piece')], max_length=10, verbose_name='Unit for amount')),
|
||||||
|
('ingredient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='food_planner.Ingredient')),
|
||||||
|
('recipe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='food_planner.Recipe')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='StoredIngredients',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('amount', models.PositiveIntegerField(help_text='Please specify the stored amount of the ingredient', verbose_name='Amount')),
|
||||||
|
('unit', models.CharField(choices=[('KG', 'kg'), ('G', 'g'), ('MG', 'mg'), ('L', 'l'), ('ML', 'ml'), ('TEA', 'teaspoon'), ('TBL', 'tablespoon'), ('PINCH', 'pinch'), ('PIECE', 'piece')], max_length=10, verbose_name='Unit for amount')),
|
||||||
|
('ingredient', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='food_planner.Ingredient')),
|
||||||
|
('pantry', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='food_planner.Pantry')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='recipe',
|
||||||
|
name='ingredients',
|
||||||
|
field=models.ManyToManyField(through='food_planner.UsedIngredients', to='food_planner.Ingredient'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='recipe',
|
||||||
|
name='kitchen_utilities',
|
||||||
|
field=models.ManyToManyField(through='food_planner.UsedKitchenUtilities', to='food_planner.KitchenUtility'),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Profile',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('daily_fat_demand', models.PositiveIntegerField(default=117, help_text='At most this amount of fat is needed per day', verbose_name='Daily fat demand')),
|
||||||
|
('daily_carbohydrate_demand', models.PositiveIntegerField(default=150, help_text='At most this amount of carbohydrates is needed per day', verbose_name='Daily carbohydrate demand')),
|
||||||
|
('daily_sugar_demand', models.PositiveIntegerField(default=25, help_text='At most this amount of sugar is needed per day', verbose_name='Daily sugar demand')),
|
||||||
|
('daily_roughage_demand', models.PositiveIntegerField(default=30, help_text='At least this amount of roughage should be eaten per day', verbose_name='Daily roughage demand')),
|
||||||
|
('daily_protein_demand', models.PositiveIntegerField(default=90, help_text='At most this amount of protein should be eaten per day', verbose_name='Daily protein demand')),
|
||||||
|
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Product',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=255, verbose_name='Product')),
|
||||||
|
('amount', models.PositiveIntegerField(help_text='Please specify the provided amount of the ingredient', verbose_name='Amount')),
|
||||||
|
('unit', models.CharField(choices=[('KG', 'kg'), ('G', 'g'), ('MG', 'mg'), ('L', 'l'), ('ML', 'ml'), ('TEA', 'teaspoon'), ('TBL', 'tablespoon'), ('PINCH', 'pinch'), ('PIECE', 'piece')], max_length=10, verbose_name='Unit for amount')),
|
||||||
|
('price', models.DecimalField(blank=True, decimal_places=2, default=0.0, max_digits=4, verbose_name='Price')),
|
||||||
|
('ingredient', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='food_planner.Ingredient')),
|
||||||
|
('vendor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='food_planner.Vendor')),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='pantry',
|
||||||
|
name='ingredients',
|
||||||
|
field=models.ManyToManyField(through='food_planner.StoredIngredients', to='food_planner.Ingredient'),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='pantry',
|
||||||
|
name='owner',
|
||||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='RecipeStep',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('image', models.ImageField(blank=True, null=True, upload_to='', verbose_name='Image')),
|
||||||
|
('description', models.TextField(verbose_name='Description')),
|
||||||
|
('number_of_step', models.PositiveIntegerField(verbose_name='Number of step')),
|
||||||
|
('recipe', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='food_planner.Recipe')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'unique_together': {('recipe', 'number_of_step')},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
@ -1,11 +1,152 @@
|
|||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.utils.text import format_lazy
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
|
MEASUREMENT_UNITS = [('KG', 'kg'),
|
||||||
|
('G', 'g'),
|
||||||
|
('MG', 'mg'),
|
||||||
|
('L', 'l'),
|
||||||
|
('ML', 'ml'),
|
||||||
|
('TEA', _('teaspoon')),
|
||||||
|
('TBL', _('tablespoon')),
|
||||||
|
('PINCH', _('pinch')),
|
||||||
|
('PIECE', _('piece'))]
|
||||||
|
|
||||||
|
|
||||||
class Profile(models.Model):
|
class Profile(models.Model):
|
||||||
user = models.OneToOneField(User, models.CASCADE)
|
user = models.OneToOneField(User, models.CASCADE)
|
||||||
|
daily_fat_demand = models.PositiveIntegerField(_('Daily fat demand'),
|
||||||
|
help_text=_('At most this amount of fat is needed per day'),
|
||||||
|
default=117)
|
||||||
|
daily_carbohydrate_demand = models.PositiveIntegerField(
|
||||||
|
_('Daily carbohydrate demand'),
|
||||||
|
help_text=_('At most this amount of carbohydrates is needed per day'),
|
||||||
|
default=150)
|
||||||
|
daily_sugar_demand = models.PositiveIntegerField(_('Daily sugar demand'),
|
||||||
|
help_text=_('At most this amount of sugar is needed per day'),
|
||||||
|
default=25)
|
||||||
|
daily_roughage_demand = models.PositiveIntegerField(
|
||||||
|
_('Daily roughage demand'),
|
||||||
|
help_text=_('At least this amount of roughage should be eaten per day'),
|
||||||
|
default=30)
|
||||||
|
daily_protein_demand = models.PositiveIntegerField(
|
||||||
|
_('Daily protein demand'),
|
||||||
|
help_text=_('At most this amount of protein should be eaten per day'),
|
||||||
|
default=90)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.user.username
|
return self.user.username
|
||||||
|
|
||||||
|
|
||||||
|
class KitchenUtility(models.Model):
|
||||||
|
name = models.CharField(_('Name'), max_length=255)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
class Ingredient(models.Model):
|
||||||
|
name = models.CharField(_('Name'), max_length=255)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
class Recipe(models.Model):
|
||||||
|
author = models.ForeignKey(User, models.SET_NULL, null=True)
|
||||||
|
kitchen_utilities = models.ManyToManyField(KitchenUtility,
|
||||||
|
through='UsedKitchenUtilities')
|
||||||
|
ingredients = models.ManyToManyField(Ingredient, through='UsedIngredients')
|
||||||
|
|
||||||
|
name = models.CharField(_('Name'), max_length=255)
|
||||||
|
image = models.ImageField(_('Image'), blank=True, null=True)
|
||||||
|
experience_level = models.CharField(_('Required cooking experience'), max_length=255,
|
||||||
|
choices=[
|
||||||
|
('NOV', _('Novice')),
|
||||||
|
('INT', _('Intermediate')),
|
||||||
|
('ADV', _('Advanced')),
|
||||||
|
('EXP', _('Expert'))
|
||||||
|
])
|
||||||
|
|
||||||
|
fat = models.PositiveIntegerField(_('Fat'),
|
||||||
|
help_text=_('How much fat does one portion contain?'))
|
||||||
|
carbohydrates = models.PositiveIntegerField(_('Carbohydrates'),
|
||||||
|
help_text=_('How much carbohydrates does one portion contain?'))
|
||||||
|
sugar = models.PositiveIntegerField(_('Sugar'),
|
||||||
|
help_text=_('How much sugar does one portion contain?'))
|
||||||
|
roughage = models.PositiveIntegerField(_('Roughage'),
|
||||||
|
help_text=_('How much roughage does one portion contain?'))
|
||||||
|
protein = models.PositiveIntegerField(_('Protein'),
|
||||||
|
help_text=_('How much protein does one portion contain?'))
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
class RecipeStep(models.Model):
|
||||||
|
recipe = models.ForeignKey(Recipe, models.CASCADE)
|
||||||
|
image = models.ImageField(_('Image'), blank=True, null=True)
|
||||||
|
description = models.TextField(_('Description'))
|
||||||
|
number_of_step = models.PositiveIntegerField(_('Number of step'))
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
unique_together = ['recipe', 'number_of_step']
|
||||||
|
|
||||||
|
|
||||||
|
class UsedKitchenUtilities(models.Model):
|
||||||
|
recipe = models.ForeignKey(Recipe, models.CASCADE)
|
||||||
|
kitchen_utility = models.ForeignKey(KitchenUtility, models.CASCADE)
|
||||||
|
amount = models.PositiveIntegerField(_('Amount'),
|
||||||
|
help_text=_('How often is this kitchen utility used?'),
|
||||||
|
default=1)
|
||||||
|
|
||||||
|
|
||||||
|
class UsedIngredients(models.Model):
|
||||||
|
recipe = models.ForeignKey(Recipe, models.CASCADE)
|
||||||
|
ingredient = models.ForeignKey(Ingredient, models.CASCADE)
|
||||||
|
amount = models.PositiveIntegerField(_('Amount'),
|
||||||
|
help_text=_('Please specify the used amount of the ingredient'))
|
||||||
|
unit = models.CharField(_('Unit for amount'), max_length=10, choices=MEASUREMENT_UNITS)
|
||||||
|
|
||||||
|
class Vendor(models.Model):
|
||||||
|
name = models.CharField(_('Vendor'), max_length=50)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
class Product(models.Model):
|
||||||
|
name = models.CharField(_('Product'), max_length=255)
|
||||||
|
vendor = models.ForeignKey(Vendor, models.CASCADE)
|
||||||
|
ingredient = models.ForeignKey(Ingredient, models.SET_NULL, null=True)
|
||||||
|
amount = models.PositiveIntegerField(_('Amount'),
|
||||||
|
help_text=_('Please specify the provided amount of the ingredient'))
|
||||||
|
unit = models.CharField(_('Unit for amount'), max_length=10,
|
||||||
|
choices=MEASUREMENT_UNITS)
|
||||||
|
price = models.DecimalField(_('Price'), decimal_places=2, max_digits=4,
|
||||||
|
blank=True, default=0.0)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
|
class Pantry(models.Model):
|
||||||
|
owner = models.ForeignKey(User, models.CASCADE)
|
||||||
|
ingredients = models.ManyToManyField(Ingredient, through='StoredIngredients')
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return format_lazy('Pantry of {firstName} {lastName}',
|
||||||
|
firstName=self.owner.first_name,
|
||||||
|
lastName=self.owner.last_name)
|
||||||
|
|
||||||
|
|
||||||
|
class StoredIngredients(models.Model):
|
||||||
|
pantry = models.ForeignKey(Pantry, models.CASCADE)
|
||||||
|
ingredient = models.ForeignKey(Ingredient, models.CASCADE)
|
||||||
|
amount = models.PositiveIntegerField(_('Amount'),
|
||||||
|
help_text=_('Please specify the stored amount of the ingredient'))
|
||||||
|
unit = models.CharField(_('Unit for amount'), max_length=10,
|
||||||
|
choices=MEASUREMENT_UNITS)
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
django==3.0.3
|
django==3.0.3
|
||||||
django-crispy-forms==1.8.1
|
django-crispy-forms==1.8.1
|
||||||
django-modeltranslation==0.14.2
|
django-modeltranslation==0.14.2
|
||||||
|
Pillow==7.0.0
|
||||||
|
|||||||
Reference in New Issue
Block a user