mirror of
https://github.com/TandoorRecipes/recipes.git
synced 2026-01-03 13:19:16 -05:00
added recipe properties
This commit is contained in:
@@ -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, FoodPropertyType, FoodProperty)
|
||||
TelegramBot, Unit, UserFile, UserPreference, ViewLog, Automation, UserSpace, UnitConversion, PropertyType, FoodProperty)
|
||||
|
||||
|
||||
class CustomUserAdmin(UserAdmin):
|
||||
@@ -331,7 +331,7 @@ class FoodPropertyTypeAdmin(admin.ModelAdmin):
|
||||
list_display = ('id', 'name')
|
||||
|
||||
|
||||
admin.site.register(FoodPropertyType, FoodPropertyTypeAdmin)
|
||||
admin.site.register(PropertyType, FoodPropertyTypeAdmin)
|
||||
|
||||
|
||||
class FoodPropertyAdmin(admin.ModelAdmin):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from django.db.models import Q
|
||||
|
||||
from cookbook.models import Unit, SupermarketCategory, FoodProperty, FoodPropertyType, Supermarket, SupermarketCategoryRelation, Food, Automation, UnitConversion
|
||||
from cookbook.models import Unit, SupermarketCategory, FoodProperty, PropertyType, Supermarket, SupermarketCategoryRelation, Food, Automation, UnitConversion
|
||||
|
||||
|
||||
class OpenDataImporter:
|
||||
@@ -55,14 +55,14 @@ class OpenDataImporter:
|
||||
|
||||
insert_list = []
|
||||
for k in list(self.data[datatype].keys()):
|
||||
insert_list.append(FoodPropertyType(
|
||||
insert_list.append(PropertyType(
|
||||
name=self.data[datatype][k]['name'],
|
||||
unit=self.data[datatype][k]['unit'],
|
||||
open_data_slug=k,
|
||||
space=self.request.space
|
||||
))
|
||||
|
||||
return FoodPropertyType.objects.bulk_create(insert_list, update_conflicts=True, update_fields=('open_data_slug',), unique_fields=('space', 'name',))
|
||||
return PropertyType.objects.bulk_create(insert_list, update_conflicts=True, update_fields=('open_data_slug',), unique_fields=('space', 'name',))
|
||||
|
||||
def import_supermarket(self):
|
||||
datatype = 'supermarket'
|
||||
@@ -114,7 +114,7 @@ class OpenDataImporter:
|
||||
existing_objects[f[2]] = f
|
||||
|
||||
self._update_slug_cache(Unit, 'unit')
|
||||
self._update_slug_cache(FoodPropertyType, 'property')
|
||||
self._update_slug_cache(PropertyType, 'property')
|
||||
|
||||
pref_unit_key = 'preferred_unit_metric'
|
||||
pref_shopping_unit_key = 'preferred_packaging_unit_metric'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from cookbook.models import FoodPropertyType, Unit, Food, FoodProperty, Recipe, Step
|
||||
from cookbook.models import PropertyType, Unit, Food, FoodProperty, Recipe, Step
|
||||
|
||||
|
||||
class FoodPropertyHelper:
|
||||
@@ -19,7 +19,7 @@ class FoodPropertyHelper:
|
||||
"""
|
||||
ingredients = []
|
||||
computed_properties = {}
|
||||
property_types = FoodPropertyType.objects.filter(space=self.space).all()
|
||||
property_types = PropertyType.objects.filter(space=self.space).all()
|
||||
|
||||
for s in recipe.steps.all():
|
||||
ingredients += s.ingredients.all()
|
||||
@@ -64,10 +64,10 @@ class FoodPropertyHelper:
|
||||
food_1 = Food.objects.create(name='Food 1', space=self.space)
|
||||
food_2 = Food.objects.create(name='Food 2', space=self.space)
|
||||
|
||||
property_fat = FoodPropertyType.objects.create(name='Fat', unit='g', space=self.space)
|
||||
property_calories = FoodPropertyType.objects.create(name='Calories', unit='kcal', space=self.space)
|
||||
property_nuts = FoodPropertyType.objects.create(name='Nuts', space=self.space)
|
||||
property_price = FoodPropertyType.objects.create(name='Price', unit='€', space=self.space)
|
||||
property_fat = PropertyType.objects.create(name='Fat', unit='g', space=self.space)
|
||||
property_calories = PropertyType.objects.create(name='Calories', unit='kcal', space=self.space)
|
||||
property_nuts = PropertyType.objects.create(name='Nuts', space=self.space)
|
||||
property_price = PropertyType.objects.create(name='Price', unit='€', space=self.space)
|
||||
|
||||
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=self.space)
|
||||
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=self.space)
|
||||
@@ -87,3 +87,18 @@ class FoodPropertyHelper:
|
||||
step_2 = Step.objects.create(instruction='instruction_step_1', space=self.space)
|
||||
step_2.ingredients.create(amount=50, unit=unit_gram, food=food_1, space=self.space)
|
||||
recipe_1.steps.add(step_2)
|
||||
|
||||
|
||||
class RecipePropertyHelper:
|
||||
space = None
|
||||
|
||||
def __init__(self, space):
|
||||
"""
|
||||
Helper to perform recipe property operations
|
||||
:param space: space to limit scope to
|
||||
"""
|
||||
self.space = space
|
||||
|
||||
|
||||
def parse_properties_from_schema(self, schema):
|
||||
pass
|
||||
@@ -1,5 +1,6 @@
|
||||
# import random
|
||||
import re
|
||||
import traceback
|
||||
from html import unescape
|
||||
|
||||
from django.core.cache import caches
|
||||
@@ -12,7 +13,8 @@ from recipe_scrapers._utils import get_host_name, get_minutes
|
||||
|
||||
# from cookbook.helper import recipe_url_import as helper
|
||||
from cookbook.helper.ingredient_parser import IngredientParser
|
||||
from cookbook.models import Automation, Keyword
|
||||
from cookbook.models import Automation, Keyword, PropertyType
|
||||
|
||||
|
||||
# from unicodedata import decomposition
|
||||
|
||||
@@ -193,6 +195,13 @@ def get_from_scraper(scrape, request):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
try:
|
||||
recipe_json['properties'] = get_recipe_properties(request.space, scrape.schema.nutrients())
|
||||
print(recipe_json['properties'])
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
pass
|
||||
|
||||
if recipe_json['source_url']:
|
||||
automations = Automation.objects.filter(type=Automation.INSTRUCTION_REPLACE, space=request.space, disabled=False).only('param_1', 'param_2', 'param_3').order_by('order').all()[:512]
|
||||
for a in automations:
|
||||
@@ -203,6 +212,30 @@ def get_from_scraper(scrape, request):
|
||||
return recipe_json
|
||||
|
||||
|
||||
def get_recipe_properties(space, property_data):
|
||||
# {'servingSize': '1', 'calories': '302 kcal', 'proteinContent': '7,66g', 'fatContent': '11,56g', 'carbohydrateContent': '41,33g'}
|
||||
properties = {
|
||||
"property-calories": "calories",
|
||||
"property-carbohydrates": "carbohydrateContent",
|
||||
"property-proteins": "proteinContent",
|
||||
"property-fats": "fatContent",
|
||||
}
|
||||
recipe_properties = []
|
||||
for pt in PropertyType.objects.filter(space=space, open_data_slug__in=list(properties.keys())).all():
|
||||
for p in list(properties.keys()):
|
||||
if pt.open_data_slug == p:
|
||||
if properties[p] in property_data:
|
||||
recipe_properties.append({
|
||||
'property_type': {
|
||||
'id': pt.id,
|
||||
'name': pt.name,
|
||||
},
|
||||
'property_amount': parse_servings(property_data[properties[p]]) / float(property_data['servingSize']),
|
||||
})
|
||||
|
||||
return recipe_properties
|
||||
|
||||
|
||||
def get_from_youtube_scraper(url, request):
|
||||
"""A YouTube Information Scraper."""
|
||||
kw, created = Keyword.objects.get_or_create(name='YouTube', space=request.space)
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# Generated by Django 4.1.7 on 2023-05-06 16:33
|
||||
|
||||
import cookbook.models
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('cookbook', '0194_supermarketcategoryrelation_unique_sm_category_relation'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameModel(
|
||||
old_name='FoodPropertyType',
|
||||
new_name='PropertyType',
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='RecipeProperty',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('property_amount', models.DecimalField(decimal_places=4, default=0, max_digits=32)),
|
||||
('property_type', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cookbook.propertytype')),
|
||||
('space', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='cookbook.space')),
|
||||
],
|
||||
bases=(models.Model, cookbook.models.PermissionModelMixin),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='recipe',
|
||||
name='properties',
|
||||
field=models.ManyToManyField(blank=True, to='cookbook.recipeproperty'),
|
||||
),
|
||||
]
|
||||
@@ -755,7 +755,7 @@ class Step(ExportModelOperationsMixin('step'), models.Model, PermissionModelMixi
|
||||
indexes = (GinIndex(fields=["search_vector"]),)
|
||||
|
||||
|
||||
class FoodPropertyType(models.Model, PermissionModelMixin):
|
||||
class PropertyType(models.Model, PermissionModelMixin):
|
||||
NUTRITION = 'NUTRITION'
|
||||
ALLERGEN = 'ALLERGEN'
|
||||
PRICE = 'PRICE'
|
||||
@@ -780,7 +780,7 @@ class FoodPropertyType(models.Model, PermissionModelMixin):
|
||||
|
||||
class Meta:
|
||||
constraints = [
|
||||
models.UniqueConstraint(fields=['space', 'name'], name='food_property_type_unique_name_per_space')
|
||||
models.UniqueConstraint(fields=['space', 'name'], name='property_type_unique_name_per_space')
|
||||
]
|
||||
|
||||
|
||||
@@ -789,7 +789,7 @@ class FoodProperty(models.Model, PermissionModelMixin):
|
||||
food_unit = models.ForeignKey(Unit, on_delete=models.CASCADE)
|
||||
food = models.ForeignKey(Food, on_delete=models.CASCADE)
|
||||
property_amount = models.DecimalField(default=0, decimal_places=4, max_digits=32)
|
||||
property_type = models.ForeignKey(FoodPropertyType, on_delete=models.PROTECT)
|
||||
property_type = models.ForeignKey(PropertyType, on_delete=models.PROTECT)
|
||||
|
||||
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
||||
objects = ScopedManager(space='space')
|
||||
@@ -803,6 +803,17 @@ class FoodProperty(models.Model, PermissionModelMixin):
|
||||
]
|
||||
|
||||
|
||||
class RecipeProperty(models.Model, PermissionModelMixin):
|
||||
property_amount = models.DecimalField(default=0, decimal_places=4, max_digits=32)
|
||||
property_type = models.ForeignKey(PropertyType, on_delete=models.PROTECT)
|
||||
|
||||
space = models.ForeignKey(Space, on_delete=models.CASCADE)
|
||||
objects = ScopedManager(space='space')
|
||||
|
||||
def __str__(self):
|
||||
return f'{self.property_amount} {self.property_type.unit} {self.property_type.name}'
|
||||
|
||||
|
||||
class NutritionInformation(models.Model, PermissionModelMixin):
|
||||
fats = models.DecimalField(default=0, decimal_places=16, max_digits=32)
|
||||
carbohydrates = models.DecimalField(
|
||||
@@ -841,6 +852,7 @@ class Recipe(ExportModelOperationsMixin('recipe'), models.Model, PermissionModel
|
||||
waiting_time = models.IntegerField(default=0)
|
||||
internal = models.BooleanField(default=False)
|
||||
nutrition = models.ForeignKey(NutritionInformation, blank=True, null=True, on_delete=models.CASCADE)
|
||||
properties = models.ManyToManyField(RecipeProperty, blank=True)
|
||||
show_ingredient_overview = models.BooleanField(default=True)
|
||||
private = models.BooleanField(default=False)
|
||||
shared = models.ManyToManyField(User, blank=True, related_name='recipe_shared_with')
|
||||
|
||||
@@ -22,7 +22,7 @@ from rest_framework.exceptions import NotFound, ValidationError
|
||||
|
||||
from cookbook.helper.CustomStorageClass import CachedS3Boto3Storage
|
||||
from cookbook.helper.HelperFunctions import str2bool
|
||||
from cookbook.helper.food_property_helper import FoodPropertyHelper
|
||||
from cookbook.helper.property_helper import FoodPropertyHelper
|
||||
from cookbook.helper.permission_helper import above_space_limit
|
||||
from cookbook.helper.shopping_helper import RecipeShoppingEditor
|
||||
from cookbook.helper.unit_conversion_helper import UnitConversionHelper
|
||||
@@ -33,7 +33,7 @@ from cookbook.models import (Automation, BookmarkletImport, Comment, CookLog, Cu
|
||||
ShoppingListEntry, ShoppingListRecipe, Space, Step, Storage,
|
||||
Supermarket, SupermarketCategory, SupermarketCategoryRelation, Sync,
|
||||
SyncLog, Unit, UserFile, UserPreference, UserSpace, ViewLog, UnitConversion, FoodProperty,
|
||||
FoodPropertyType)
|
||||
PropertyType, RecipeProperty)
|
||||
from cookbook.templatetags.custom_tags import markdown
|
||||
from recipes.settings import AWS_ENABLED, MEDIA_URL
|
||||
|
||||
@@ -744,21 +744,21 @@ class UnitConversionSerializer(WritableNestedModelSerializer):
|
||||
|
||||
class Meta:
|
||||
model = UnitConversion
|
||||
fields = ('id', 'name','base_amount', 'base_unit', 'converted_amount', 'converted_unit', 'food', 'open_data_slug')
|
||||
fields = ('id', 'name', 'base_amount', 'base_unit', 'converted_amount', 'converted_unit', 'food', 'open_data_slug')
|
||||
|
||||
|
||||
class FoodPropertyTypeSerializer(serializers.ModelSerializer):
|
||||
class PropertyTypeSerializer(serializers.ModelSerializer):
|
||||
def create(self, validated_data):
|
||||
validated_data['space'] = self.context['request'].space
|
||||
return super().create(validated_data)
|
||||
|
||||
class Meta:
|
||||
model = FoodPropertyType
|
||||
model = PropertyType
|
||||
fields = ('id', 'name', 'icon', 'unit', 'description', 'open_data_slug')
|
||||
|
||||
|
||||
class FoodPropertySerializer(UniqueFieldsMixin, WritableNestedModelSerializer):
|
||||
property_type = FoodPropertyTypeSerializer()
|
||||
property_type = PropertyTypeSerializer()
|
||||
food = FoodSimpleSerializer()
|
||||
food_unit = UnitSerializer()
|
||||
food_amount = CustomDecimalField()
|
||||
@@ -776,6 +776,20 @@ class FoodPropertySerializer(UniqueFieldsMixin, WritableNestedModelSerializer):
|
||||
read_only_fields = ('id',)
|
||||
|
||||
|
||||
class RecipePropertySerializer(UniqueFieldsMixin, WritableNestedModelSerializer):
|
||||
property_type = PropertyTypeSerializer()
|
||||
property_amount = CustomDecimalField()
|
||||
|
||||
def create(self, validated_data):
|
||||
validated_data['space'] = self.context['request'].space
|
||||
return super().create(validated_data)
|
||||
|
||||
class Meta:
|
||||
model = RecipeProperty
|
||||
fields = ('id', 'property_type', 'property_amount',)
|
||||
read_only_fields = ('id',)
|
||||
|
||||
|
||||
class NutritionInformationSerializer(serializers.ModelSerializer):
|
||||
carbohydrates = CustomDecimalField()
|
||||
fats = CustomDecimalField()
|
||||
@@ -826,6 +840,7 @@ class RecipeOverviewSerializer(RecipeBaseSerializer):
|
||||
|
||||
class RecipeSerializer(RecipeBaseSerializer):
|
||||
nutrition = NutritionInformationSerializer(allow_null=True, required=False)
|
||||
properties = RecipePropertySerializer(many=True, required=False)
|
||||
steps = StepSerializer(many=True)
|
||||
keywords = KeywordSerializer(many=True)
|
||||
shared = UserSerializer(many=True, required=False)
|
||||
@@ -842,7 +857,7 @@ class RecipeSerializer(RecipeBaseSerializer):
|
||||
fields = (
|
||||
'id', 'name', 'description', 'image', 'keywords', 'steps', 'working_time',
|
||||
'waiting_time', 'created_by', 'created_at', 'updated_at', 'source_url',
|
||||
'internal', 'show_ingredient_overview', 'nutrition', 'food_properties', 'servings', 'file_path', 'servings_text', 'rating',
|
||||
'internal', 'show_ingredient_overview', 'nutrition', 'properties', 'food_properties', 'servings', 'file_path', 'servings_text', 'rating',
|
||||
'last_cooked',
|
||||
'private', 'shared',
|
||||
)
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<a href="{% url 'list_food_property_type' %}" class="p-0 p-md-1">
|
||||
<a href="{% url 'list_property_type' %}" class="p-0 p-md-1">
|
||||
<div class="card p-0 no-gutters border-0">
|
||||
<div class="card-body text-center p-0 no-gutters">
|
||||
<i class="fas fa-database fa-2x"></i>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
from django.contrib import auth
|
||||
from django_scopes import scopes_disabled
|
||||
|
||||
from cookbook.helper.food_property_helper import FoodPropertyHelper
|
||||
from cookbook.models import Unit, Food, FoodPropertyType, FoodProperty, Recipe, Step
|
||||
from cookbook.helper.property_helper import FoodPropertyHelper
|
||||
from cookbook.models import Unit, Food, PropertyType, FoodProperty, Recipe, Step
|
||||
|
||||
|
||||
def test_food_property(space_1, u1_s1):
|
||||
@@ -16,10 +16,10 @@ def test_food_property(space_1, u1_s1):
|
||||
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)
|
||||
property_fat = PropertyType.objects.create(name='property_fat', space=space_1)
|
||||
property_calories = PropertyType.objects.create(name='property_calories', space=space_1)
|
||||
property_nuts = PropertyType.objects.create(name='property_nuts', space=space_1)
|
||||
property_price = PropertyType.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)
|
||||
|
||||
@@ -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, FoodPropertyType, UnitConversion)
|
||||
get_model_name, UserSpace, Space, PropertyType, UnitConversion)
|
||||
from .views import api, data, delete, edit, import_export, lists, new, telegram, views
|
||||
from .views.api import CustomAuthToken, ImportOpenData
|
||||
|
||||
@@ -193,7 +193,7 @@ for m in generic_models:
|
||||
)
|
||||
)
|
||||
|
||||
vue_models = [Food, Keyword, Unit, Supermarket, SupermarketCategory, Automation, UserFile, Step, CustomFilter, UnitConversion, FoodPropertyType]
|
||||
vue_models = [Food, Keyword, Unit, Supermarket, SupermarketCategory, Automation, UserFile, Step, CustomFilter, UnitConversion, PropertyType]
|
||||
for m in vue_models:
|
||||
py_name = get_model_name(m)
|
||||
url_name = py_name.replace('_', '-')
|
||||
|
||||
@@ -70,7 +70,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, FoodPropertyType, FoodProperty)
|
||||
SyncLog, Unit, UserFile, UserPreference, UserSpace, ViewLog, UnitConversion, PropertyType, FoodProperty)
|
||||
from cookbook.provider.dropbox import Dropbox
|
||||
from cookbook.provider.local import Local
|
||||
from cookbook.provider.nextcloud import Nextcloud
|
||||
@@ -94,7 +94,7 @@ from cookbook.serializer import (AutomationSerializer, BookmarkletImportListSeri
|
||||
SyncLogSerializer, SyncSerializer, UnitSerializer,
|
||||
UserFileSerializer, UserSerializer, UserPreferenceSerializer,
|
||||
UserSpaceSerializer, ViewLogSerializer, AccessTokenSerializer, FoodSimpleSerializer,
|
||||
RecipeExportSerializer, UnitConversionSerializer, FoodPropertyTypeSerializer, FoodPropertySerializer)
|
||||
RecipeExportSerializer, UnitConversionSerializer, PropertyTypeSerializer, FoodPropertySerializer)
|
||||
from cookbook.views.import_export import get_integration
|
||||
from recipes import settings
|
||||
|
||||
@@ -811,8 +811,12 @@ class RecipeViewSet(viewsets.ModelViewSet):
|
||||
|
||||
if self.detail: # if detail request and not list, private condition is verified by permission class
|
||||
if not share: # filter for space only if not shared
|
||||
self.queryset = self.queryset.filter(space=self.request.space).prefetch_related('steps', 'keywords',
|
||||
self.queryset = self.queryset.filter(space=self.request.space).prefetch_related(
|
||||
'keywords',
|
||||
'shared',
|
||||
'properties',
|
||||
'properties__property_type',
|
||||
'steps',
|
||||
'steps__ingredients',
|
||||
'steps__ingredients__step_set',
|
||||
'steps__ingredients__step_set__recipe_set',
|
||||
@@ -831,9 +835,8 @@ class RecipeViewSet(viewsets.ModelViewSet):
|
||||
'steps__ingredients__unit__unit_conversion_base_relation__base_unit',
|
||||
'steps__ingredients__unit__unit_conversion_converted_relation',
|
||||
'steps__ingredients__unit__unit_conversion_converted_relation__converted_unit',
|
||||
'cooklog_set').select_related('nutrition')
|
||||
|
||||
'cooklog_set').select_related(
|
||||
'nutrition')
|
||||
return super().get_queryset()
|
||||
|
||||
self.queryset = self.queryset.filter(space=self.request.space).filter(
|
||||
@@ -972,8 +975,8 @@ class UnitConversionViewSet(viewsets.ModelViewSet):
|
||||
|
||||
|
||||
class FoodPropertyTypeViewSet(viewsets.ModelViewSet):
|
||||
queryset = FoodPropertyType.objects
|
||||
serializer_class = FoodPropertyTypeSerializer
|
||||
queryset = PropertyType.objects
|
||||
serializer_class = PropertyTypeSerializer
|
||||
permission_classes = [CustomIsUser & CustomTokenHasReadWriteScope]
|
||||
|
||||
def get_queryset(self):
|
||||
|
||||
@@ -246,15 +246,15 @@ def unit_conversion(request):
|
||||
|
||||
|
||||
@group_required('user')
|
||||
def food_property_type(request):
|
||||
def property_type(request):
|
||||
# model-name is the models.js name of the model, probably ALL-CAPS
|
||||
return render(
|
||||
request,
|
||||
'generic/model_template.html',
|
||||
{
|
||||
"title": _("Food Property Types"),
|
||||
"title": _("Property Types"),
|
||||
"config": {
|
||||
'model': "FOOD_PROPERTY_TYPE", # *REQUIRED* name of the model in models.js
|
||||
'model': "PROPERTY_TYPE", # *REQUIRED* name of the model in models.js
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ from oauth2_provider.models import AccessToken
|
||||
from cookbook.forms import (CommentForm, Recipe, SearchPreferenceForm, ShoppingPreferenceForm,
|
||||
SpaceCreateForm, SpaceJoinForm, User,
|
||||
UserCreateForm, UserNameForm, UserPreference, UserPreferenceForm)
|
||||
from cookbook.helper.food_property_helper import FoodPropertyHelper
|
||||
from cookbook.helper.property_helper import FoodPropertyHelper
|
||||
from cookbook.helper.permission_helper import group_required, has_group_permission, share_link_valid, switch_user_active_space
|
||||
from cookbook.models import (Comment, CookLog, InviteLink, SearchFields, SearchPreference, ShareLink,
|
||||
Space, ViewLog, UserSpace)
|
||||
|
||||
Reference in New Issue
Block a user