basic food property calculation

This commit is contained in:
vabene1111 2023-03-25 07:46:06 +01:00
parent 9241638686
commit 6d5592c1be
17 changed files with 228 additions and 195 deletions

View File

@ -15,7 +15,7 @@ from .models import (BookmarkletImport, Comment, CookLog, Food, FoodInheritField
Recipe, RecipeBook, RecipeBookEntry, RecipeImport, SearchPreference, ShareLink,
ShoppingList, ShoppingListEntry, ShoppingListRecipe, Space, Step, Storage,
Supermarket, SupermarketCategory, SupermarketCategoryRelation, Sync, SyncLog,
TelegramBot, Unit, UserFile, UserPreference, ViewLog, Automation, UserSpace, UnitConversion, NutritionType, FoodNutrition)
TelegramBot, Unit, UserFile, UserPreference, ViewLog, Automation, UserSpace, UnitConversion, FoodPropertyType, FoodProperty)
class CustomUserAdmin(UserAdmin):
@ -327,18 +327,18 @@ class ShareLinkAdmin(admin.ModelAdmin):
admin.site.register(ShareLink, ShareLinkAdmin)
class NutritionTypeAdmin(admin.ModelAdmin):
class FoodPropertyTypeAdmin(admin.ModelAdmin):
list_display = ('id', 'name')
admin.site.register(NutritionType, NutritionTypeAdmin)
admin.site.register(FoodPropertyType, FoodPropertyTypeAdmin)
class FoodNutritionAdmin(admin.ModelAdmin):
list_display = ('id', 'food_amount', 'food_unit', 'food', 'nutrition_amount', 'nutrition_type')
class FoodPropertyAdmin(admin.ModelAdmin):
list_display = ('id', 'food_amount', 'food_unit', 'food', 'property_amount', 'property_type')
admin.site.register(FoodNutrition, FoodNutritionAdmin)
admin.site.register(FoodProperty, FoodPropertyAdmin)
class NutritionInformationAdmin(admin.ModelAdmin):

View File

@ -0,0 +1,29 @@
from cookbook.models import FoodPropertyType
def calculate_recipe_properties(recipe):
ingredients = []
computed_properties = {}
for s in recipe.steps.all():
ingredients += s.ingredients.all()
for fpt in FoodPropertyType.objects.filter(space=recipe.space).all(): # TODO is this safe or should I require the request context?
computed_properties[fpt.id] = {'name': fpt.name, 'food_values': {}, 'total_value': 0}
# TODO unit conversion support
for i in ingredients:
for p in i.food.foodproperty_set.all():
computed_properties[p.property_type.id]['total_value'] += (i.amount / p.food_amount) * p.property_amount
computed_properties[p.property_type.id]['food_values'][i.food.id] = add_or_create(computed_properties[p.property_type.id]['food_values'], i.food.id, (i.amount / p.food_amount) * p.property_amount)
return computed_properties
# small dict helper to add to existing key or create new, probably a better way of doing this
def add_or_create(d, key, value):
if key in d:
d[key] += value
else:
d[key] = value
return d

View File

@ -0,0 +1,73 @@
# Generated by Django 4.1.7 on 2023-03-25 05:48
import cookbook.models
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django_prometheus.models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0188_space_no_sharing_limit'),
]
operations = [
migrations.AddField(
model_name='unit',
name='base_unit',
field=models.TextField(blank=True, default=None, max_length=256, null=True),
),
migrations.CreateModel(
name='UnitConversion',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('base_amount', models.DecimalField(decimal_places=16, default=0, max_digits=32)),
('converted_amount', models.DecimalField(decimal_places=16, default=0, max_digits=32)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('base_unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='unit_conversion_base_relation', to='cookbook.unit')),
('converted_unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='unit_conversion_converted_relation', to='cookbook.unit')),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
('food', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.food')),
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
],
bases=(django_prometheus.models.ExportModelOperationsMixin('unit_conversion'), models.Model, cookbook.models.PermissionModelMixin),
),
migrations.CreateModel(
name='FoodPropertyType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128)),
('unit', models.CharField(blank=True, max_length=64, null=True)),
('icon', models.CharField(blank=True, max_length=16, null=True)),
('description', models.CharField(blank=True, max_length=512, null=True)),
('category', models.CharField(choices=[('NUTRITION', 'Nutrition'), ('ALLERGEN', 'Allergen'), ('PRICE', 'PRICE')], max_length=64)),
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
],
bases=(models.Model, cookbook.models.PermissionModelMixin),
),
migrations.CreateModel(
name='FoodProperty',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('food_amount', models.DecimalField(decimal_places=2, default=0, max_digits=32)),
('nutrition_amount', models.DecimalField(decimal_places=4, default=0, max_digits=32)),
('food', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.food')),
('food_unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.unit')),
('nutrition_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cookbook.foodpropertytype')),
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
],
bases=(models.Model, cookbook.models.PermissionModelMixin),
),
migrations.AddConstraint(
model_name='foodpropertytype',
constraint=models.UniqueConstraint(fields=('space', 'name'), name='nutrition_type_unique_name_per_space'),
),
migrations.AddConstraint(
model_name='foodproperty',
constraint=models.UniqueConstraint(fields=('food', 'nutrition_type', 'space'), name='food_nutrition_unique_per_space'),
),
]

View File

@ -1,34 +0,0 @@
# Generated by Django 4.1.7 on 2023-02-24 19:47
import cookbook.models
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django_prometheus.models
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cookbook', '0188_space_no_sharing_limit'),
]
operations = [
migrations.CreateModel(
name='UnitConversion',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('base_amount', models.DecimalField(decimal_places=16, default=0, max_digits=32)),
('converted_amount', models.DecimalField(decimal_places=16, default=0, max_digits=32)),
('created_at', models.DateTimeField(auto_now_add=True)),
('updated_at', models.DateTimeField(auto_now=True)),
('base_unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='base_unit', to='cookbook.unit')),
('converted_unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='converted_unit', to='cookbook.unit')),
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to=settings.AUTH_USER_MODEL)),
('food', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='cookbook.food')),
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
],
bases=(django_prometheus.models.ExportModelOperationsMixin('unit_conversion'), models.Model, cookbook.models.PermissionModelMixin),
),
]

View File

@ -1,40 +0,0 @@
# Generated by Django 4.1.7 on 2023-02-24 20:15
import cookbook.models
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0189_unitconversion'),
]
operations = [
migrations.CreateModel(
name='NutritionType',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=128)),
('unit', models.CharField(blank=True, max_length=64, null=True)),
('icon', models.CharField(blank=True, max_length=16, null=True)),
('description', models.CharField(blank=True, max_length=512, null=True)),
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
],
bases=(models.Model, cookbook.models.PermissionModelMixin),
),
migrations.CreateModel(
name='FoodNutrition',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('food_amount', models.DecimalField(decimal_places=2, default=0, max_digits=32)),
('nutrition_amount', models.DecimalField(decimal_places=4, default=0, max_digits=32)),
('food', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.food')),
('food_unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.unit')),
('nutrition_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cookbook.nutritiontype')),
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
],
bases=(models.Model, cookbook.models.PermissionModelMixin),
),
]

View File

@ -0,0 +1,44 @@
# Generated by Django 4.1.7 on 2023-03-25 06:04
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0189_unit_base_unit_unitconversion_foodpropertytype_and_more'),
]
operations = [
migrations.RemoveConstraint(
model_name='foodproperty',
name='food_nutrition_unique_per_space',
),
migrations.RemoveConstraint(
model_name='foodpropertytype',
name='nutrition_type_unique_name_per_space',
),
migrations.RenameField(
model_name='foodproperty',
old_name='nutrition_amount',
new_name='property_amount',
),
migrations.RenameField(
model_name='foodproperty',
old_name='nutrition_type',
new_name='property_type',
),
migrations.AlterField(
model_name='foodpropertytype',
name='category',
field=models.CharField(blank=True, choices=[('NUTRITION', 'Nutrition'), ('ALLERGEN', 'Allergen'), ('PRICE', 'PRICE')], max_length=64, null=True),
),
migrations.AddConstraint(
model_name='foodproperty',
constraint=models.UniqueConstraint(fields=('food', 'property_type', 'space'), name='food_property_unique_per_space'),
),
migrations.AddConstraint(
model_name='foodpropertytype',
constraint=models.UniqueConstraint(fields=('space', 'name'), name='food_property_type_unique_name_per_space'),
),
]

View File

@ -1,21 +0,0 @@
# Generated by Django 4.1.7 on 2023-02-24 21:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0190_nutritiontype_foodnutrition'),
]
operations = [
migrations.AddConstraint(
model_name='foodnutrition',
constraint=models.UniqueConstraint(fields=('food', 'nutrition_type', 'space'), name='food_nutrition_unique_per_space'),
),
migrations.AddConstraint(
model_name='nutritiontype',
constraint=models.UniqueConstraint(fields=('space', 'name'), name='nutrition_type_unique_name_per_space'),
),
]

View File

@ -1,24 +0,0 @@
# Generated by Django 4.1.7 on 2023-02-26 06:30
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0191_foodnutrition_food_nutrition_unique_per_space_and_more'),
]
operations = [
migrations.AlterField(
model_name='unitconversion',
name='base_unit',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='unit_conversion_base_unit', to='cookbook.unit'),
),
migrations.AlterField(
model_name='unitconversion',
name='converted_unit',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='unit_conversion_converted_unit', to='cookbook.unit'),
),
]

View File

@ -1,24 +0,0 @@
# Generated by Django 4.1.7 on 2023-02-26 07:03
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0192_alter_unitconversion_base_unit_and_more'),
]
operations = [
migrations.AlterField(
model_name='unitconversion',
name='base_unit',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='unit_conversion_base_relation', to='cookbook.unit'),
),
migrations.AlterField(
model_name='unitconversion',
name='converted_unit',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='unit_conversion_converted_relation', to='cookbook.unit'),
),
]

View File

@ -1,18 +0,0 @@
# Generated by Django 4.1.7 on 2023-03-15 14:57
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cookbook', '0193_alter_unitconversion_base_unit_and_more'),
]
operations = [
migrations.AddField(
model_name='unit',
name='base_unit',
field=models.TextField(blank=True, default=None, max_length=256, null=True),
),
]

View File

@ -683,8 +683,6 @@ class Ingredient(ExportModelOperationsMixin('ingredient'), models.Model, Permiss
order = models.IntegerField(default=0)
original_text = models.CharField(max_length=512, null=True, blank=True, default=None)
original_text = models.CharField(max_length=512, null=True, blank=True, default=None)
space = models.ForeignKey(Space, on_delete=models.CASCADE)
objects = ScopedManager(space='space')
@ -740,11 +738,19 @@ class Step(ExportModelOperationsMixin('step'), models.Model, PermissionModelMixi
indexes = (GinIndex(fields=["search_vector"]),)
class NutritionType(models.Model, PermissionModelMixin):
class FoodPropertyType(models.Model, PermissionModelMixin):
NUTRITION = 'NUTRITION'
ALLERGEN = 'ALLERGEN'
PRICE = 'PRICE'
name = models.CharField(max_length=128)
unit = models.CharField(max_length=64, blank=True, null=True)
icon = models.CharField(max_length=16, blank=True, null=True)
description = models.CharField(max_length=512, blank=True, null=True)
category = models.CharField(max_length=64, choices=((NUTRITION, _('Nutrition')), (ALLERGEN, _('Allergen')), (PRICE, _('PRICE'))), null=True, blank=True)
# TODO show if empty property?
# TODO formatting property?
space = models.ForeignKey(Space, on_delete=models.CASCADE)
objects = ScopedManager(space='space')
@ -754,26 +760,26 @@ class NutritionType(models.Model, PermissionModelMixin):
class Meta:
constraints = [
models.UniqueConstraint(fields=['space', 'name'], name='nutrition_type_unique_name_per_space')
models.UniqueConstraint(fields=['space', 'name'], name='food_property_type_unique_name_per_space')
]
class FoodNutrition(models.Model, PermissionModelMixin):
class FoodProperty(models.Model, PermissionModelMixin):
food_amount = models.DecimalField(default=0, decimal_places=2, max_digits=32)
food_unit = models.ForeignKey(Unit, on_delete=models.CASCADE)
food = models.ForeignKey(Food, on_delete=models.CASCADE)
nutrition_amount = models.DecimalField(default=0, decimal_places=4, max_digits=32)
nutrition_type = models.ForeignKey(NutritionType, on_delete=models.PROTECT)
property_amount = models.DecimalField(default=0, decimal_places=4, max_digits=32)
property_type = models.ForeignKey(FoodPropertyType, on_delete=models.PROTECT)
space = models.ForeignKey(Space, on_delete=models.CASCADE)
objects = ScopedManager(space='space')
def __str__(self):
return f'{self.food_amount} {self.food_unit} {self.food}: {self.nutrition_amount} {self.nutrition_type.unit} {self.nutrition_type.name}'
return f'{self.food_amount} {self.food_unit} {self.food}: {self.property_amount} {self.property_type.unit} {self.property_type.name}'
class Meta:
constraints = [
models.UniqueConstraint(fields=['food', 'nutrition_type', 'space'], name='food_nutrition_unique_per_space')
models.UniqueConstraint(fields=['food', 'property_type', 'space'], name='food_property_unique_per_space')
]

View File

@ -31,8 +31,8 @@ from cookbook.models import (Automation, BookmarkletImport, Comment, CookLog, Cu
RecipeBookEntry, RecipeImport, ShareLink, ShoppingList,
ShoppingListEntry, ShoppingListRecipe, Space, Step, Storage,
Supermarket, SupermarketCategory, SupermarketCategoryRelation, Sync,
SyncLog, Unit, UserFile, UserPreference, UserSpace, ViewLog, UnitConversion, FoodNutrition,
NutritionType)
SyncLog, Unit, UserFile, UserPreference, UserSpace, ViewLog, UnitConversion, FoodProperty,
FoodPropertyType)
from cookbook.templatetags.custom_tags import markdown
from recipes.settings import AWS_ENABLED, MEDIA_URL
@ -660,12 +660,12 @@ class IngredientSimpleSerializer(WritableNestedModelSerializer):
if ingredient.food:
for fn in ingredient.food.foodnutrition_set.all():
if fn.food_unit == ingredient.unit:
nutritions[fn.nutrition_type.id] = ingredient.amount / fn.food_amount * fn.nutrition_amount
nutritions[fn.property_type.id] = ingredient.amount / fn.food_amount * fn.property_amount
else:
conversions = self.get_conversions(ingredient)
for c in conversions:
if fn.food_unit.id == c['unit']['id']:
nutritions[fn.nutrition_type.id] = c['amount'] / fn.food_amount * fn.nutrition_amount
nutritions[fn.property_type.id] = c['amount'] / fn.food_amount * fn.property_amount
return nutritions
@ -758,7 +758,7 @@ class NutritionTypeSerializer(serializers.ModelSerializer):
return super().create(validated_data)
class Meta:
model = NutritionType
model = FoodPropertyType
fields = ('id', 'name', 'icon', 'unit', 'description')

View File

@ -0,0 +1,42 @@
from django.contrib import auth
from django_scopes import scopes_disabled
from cookbook.helper.food_property_helper import calculate_recipe_properties
from cookbook.helper.unit_conversion_helper import get_conversions
from cookbook.models import Unit, Food, Ingredient, UnitConversion, FoodPropertyType, FoodProperty, Recipe, Step
def test_food_property(space_1, u1_s1):
with scopes_disabled():
unit_gram = Unit.objects.create(name='gram', base_unit='g', space=space_1)
unit_pcs = Unit.objects.create(name='pcs', base_unit='', space=space_1)
unit_floz1 = Unit.objects.create(name='fl. oz 1', base_unit='imperial_fluid_ounce', space=space_1) # US and UK use different volume systems (US vs imperial)
unit_floz2 = Unit.objects.create(name='fl. oz 2', base_unit='fluid_ounce', space=space_1)
unit_fantasy = Unit.objects.create(name='Fantasy Unit', base_unit='', space=space_1)
food_1 = Food.objects.create(name='food_1', space=space_1)
food_2 = Food.objects.create(name='food_2', space=space_1)
property_fat = FoodPropertyType.objects.create(name='property_fat', space=space_1)
property_calories = FoodPropertyType.objects.create(name='property_calories', space=space_1)
property_nuts = FoodPropertyType.objects.create(name='property_nuts', space=space_1)
property_price = FoodPropertyType.objects.create(name='property_price', space=space_1)
food_1_property_fat = FoodProperty.objects.create(food_amount=100, food_unit=unit_gram, food=food_1, property_amount=50, property_type=property_fat, space=space_1)
food_1_property_nuts = FoodProperty.objects.create(food_amount=100, food_unit=unit_gram, food=food_1, property_amount=1, property_type=property_nuts, space=space_1)
food_1_property_price = FoodProperty.objects.create(food_amount=100, food_unit=unit_gram, food=food_1, property_amount=7.50, property_type=property_price, space=space_1)
food_2_property_fat = FoodProperty.objects.create(food_amount=100, food_unit=unit_gram, food=food_2, property_amount=25, property_type=property_fat, space=space_1)
food_2_property_nuts = FoodProperty.objects.create(food_amount=100, food_unit=unit_gram, food=food_2, property_amount=0, property_type=property_nuts, space=space_1)
food_2_property_price = FoodProperty.objects.create(food_amount=100, food_unit=unit_gram, food=food_2, property_amount=2.50, property_type=property_price, space=space_1)
recipe_1 = Recipe.objects.create(name='recipe_1', waiting_time=0, working_time=0, space=space_1, created_by=auth.get_user(u1_s1))
step_1 = Step.objects.create(instruction='instruction_step_1', space=space_1)
step_1.ingredients.create(amount=500, unit=unit_gram, food=food_1, space=space_1)
step_1.ingredients.create(amount=1000, unit=unit_gram, food=food_2, space=space_1)
recipe_1.steps.add(step_1)
recipe_1.save()
property_values = calculate_recipe_properties(recipe_1)
for p in property_values:
print(p)

View File

@ -12,7 +12,7 @@ from recipes.version import VERSION_NUMBER
from .models import (Automation, Comment, CustomFilter, Food, InviteLink, Keyword, MealPlan, Recipe,
RecipeBook, RecipeBookEntry, RecipeImport, ShoppingList, Step, Storage,
Supermarket, SupermarketCategory, Sync, SyncLog, Unit, UserFile,
get_model_name, UserSpace, Space, NutritionType, UnitConversion)
get_model_name, UserSpace, Space, FoodPropertyType, UnitConversion)
from .views import api, data, delete, edit, import_export, lists, new, telegram, views
from .views.api import CustomAuthToken
@ -191,7 +191,7 @@ for m in generic_models:
)
)
vue_models = [Food, Keyword, Unit, Supermarket, SupermarketCategory, Automation, UserFile, Step, CustomFilter, UnitConversion, NutritionType]
vue_models = [Food, Keyword, Unit, Supermarket, SupermarketCategory, Automation, UserFile, Step, CustomFilter, UnitConversion, FoodPropertyType]
for m in vue_models:
py_name = get_model_name(m)
url_name = py_name.replace('_', '-')

View File

@ -68,7 +68,7 @@ from cookbook.models import (Automation, BookmarkletImport, CookLog, CustomFilte
MealType, Recipe, RecipeBook, RecipeBookEntry, ShareLink, ShoppingList,
ShoppingListEntry, ShoppingListRecipe, Space, Step, Storage,
Supermarket, SupermarketCategory, SupermarketCategoryRelation, Sync,
SyncLog, Unit, UserFile, UserPreference, UserSpace, ViewLog, UnitConversion, NutritionType)
SyncLog, Unit, UserFile, UserPreference, UserSpace, ViewLog, UnitConversion, FoodPropertyType)
from cookbook.provider.dropbox import Dropbox
from cookbook.provider.local import Local
from cookbook.provider.nextcloud import Nextcloud
@ -820,10 +820,10 @@ class RecipeViewSet(viewsets.ModelViewSet):
'steps__ingredients__food__onhand_users',
'steps__ingredients__food__substitute',
'steps__ingredients__food__child_inherit_fields',
'steps__ingredients__food__foodnutrition_set',
'steps__ingredients__food__foodnutrition_set__food',
'steps__ingredients__food__foodnutrition_set__food_unit',
'steps__ingredients__food__foodnutrition_set__nutrition_type',
# 'steps__ingredients__food__foodnutrition_set',
# 'steps__ingredients__food__foodnutrition_set__food',
# 'steps__ingredients__food__foodnutrition_set__food_unit',
# 'steps__ingredients__food__foodnutrition_set__nutrition_type',
'steps__ingredients__unit',
'steps__ingredients__unit__unit_conversion_base_relation',
'steps__ingredients__unit__unit_conversion_base_relation__base_unit',
@ -970,7 +970,7 @@ class UnitConversionViewSet(viewsets.ModelViewSet):
class NutritionTypeViewSet(viewsets.ModelViewSet):
queryset = NutritionType.objects
queryset = FoodPropertyType.objects
serializer_class = NutritionTypeSerializer
permission_classes = [CustomIsUser & CustomTokenHasReadWriteScope]

View File

@ -246,15 +246,15 @@ def unit_conversion(request):
@group_required('user')
def nutrition_type(request):
def food_property_type(request):
# model-name is the models.js name of the model, probably ALL-CAPS
return render(
request,
'generic/model_template.html',
{
"title": _("Unit Conversions"),
"title": _("Food Property Types"),
"config": {
'model': "NUTRITION_TYPE", # *REQUIRED* name of the model in models.js
'model': "FOOD_PROPERTY_TYPE", # *REQUIRED* name of the model in models.js
}
}
)

View File

@ -622,9 +622,9 @@ export class Models {
},
}
static NUTRITION_TYPE = {
name: "Nutrition Type",
apiName: "NutritionType",
static FOOD_PROPERTY_TYPE = {
name: "Food Property Type",
apiName: "FoodPropertyType",
paginated: false,
list: {
header_component: {