optimized recipe search query annotation performance
This commit is contained in:
@ -115,6 +115,10 @@ class RecipeSearch():
|
|||||||
|
|
||||||
def get_queryset(self, queryset):
|
def get_queryset(self, queryset):
|
||||||
self._queryset = queryset
|
self._queryset = queryset
|
||||||
|
self._queryset = self._queryset.prefetch_related('keywords')
|
||||||
|
self._queryset = self._queryset.annotate(rating=Avg('cooklog__rating'))
|
||||||
|
self._queryset = self._queryset.annotate(last_cooked=Max('cooklog__created_at'))
|
||||||
|
|
||||||
self._build_sort_order()
|
self._build_sort_order()
|
||||||
self._recently_viewed(num_recent=self._num_recent)
|
self._recently_viewed(num_recent=self._num_recent)
|
||||||
self._cooked_on_filter(cooked_date=self._cookedon)
|
self._cooked_on_filter(cooked_date=self._cookedon)
|
||||||
|
@ -684,25 +684,6 @@ class NutritionInformationSerializer(serializers.ModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class RecipeBaseSerializer(WritableNestedModelSerializer):
|
class RecipeBaseSerializer(WritableNestedModelSerializer):
|
||||||
def get_recipe_rating(self, obj):
|
|
||||||
try:
|
|
||||||
rating = obj.cooklog_set.filter(created_by=self.context['request'].user, rating__gt=0).aggregate(
|
|
||||||
Avg('rating'))
|
|
||||||
if rating['rating__avg']:
|
|
||||||
return rating['rating__avg']
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
return 0
|
|
||||||
|
|
||||||
def get_recipe_last_cooked(self, obj):
|
|
||||||
try:
|
|
||||||
last = obj.cooklog_set.filter(created_by=self.context['request'].user).order_by('created_at').last()
|
|
||||||
if last:
|
|
||||||
return last.created_at
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
# TODO make days of new recipe a setting
|
# TODO make days of new recipe a setting
|
||||||
def is_recipe_new(self, obj):
|
def is_recipe_new(self, obj):
|
||||||
if getattr(obj, 'new_recipe', None) or obj.created_at > (timezone.now() - timedelta(days=7)):
|
if getattr(obj, 'new_recipe', None) or obj.created_at > (timezone.now() - timedelta(days=7)):
|
||||||
@ -712,12 +693,13 @@ class RecipeBaseSerializer(WritableNestedModelSerializer):
|
|||||||
|
|
||||||
|
|
||||||
class RecipeOverviewSerializer(RecipeBaseSerializer):
|
class RecipeOverviewSerializer(RecipeBaseSerializer):
|
||||||
keywords = KeywordLabelSerializer(many=True)
|
# keywords = KeywordLabelSerializer(many=True)
|
||||||
rating = serializers.SerializerMethodField('get_recipe_rating')
|
|
||||||
last_cooked = serializers.SerializerMethodField('get_recipe_last_cooked')
|
|
||||||
new = serializers.SerializerMethodField('is_recipe_new')
|
new = serializers.SerializerMethodField('is_recipe_new')
|
||||||
recent = serializers.ReadOnlyField()
|
recent = serializers.ReadOnlyField()
|
||||||
|
|
||||||
|
rating = CustomDecimalField()
|
||||||
|
last_cooked = serializers.DateTimeField()
|
||||||
|
|
||||||
def create(self, validated_data):
|
def create(self, validated_data):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -727,7 +709,7 @@ class RecipeOverviewSerializer(RecipeBaseSerializer):
|
|||||||
class Meta:
|
class Meta:
|
||||||
model = Recipe
|
model = Recipe
|
||||||
fields = (
|
fields = (
|
||||||
'id', 'name', 'description', 'image', 'keywords', 'working_time',
|
'id', 'name', 'description', 'image', 'keywords', 'working_time',
|
||||||
'waiting_time', 'created_by', 'created_at', 'updated_at',
|
'waiting_time', 'created_by', 'created_at', 'updated_at',
|
||||||
'internal', 'servings', 'servings_text', 'rating', 'last_cooked', 'new', 'recent'
|
'internal', 'servings', 'servings_text', 'rating', 'last_cooked', 'new', 'recent'
|
||||||
)
|
)
|
||||||
@ -737,10 +719,10 @@ class RecipeOverviewSerializer(RecipeBaseSerializer):
|
|||||||
class RecipeSerializer(RecipeBaseSerializer):
|
class RecipeSerializer(RecipeBaseSerializer):
|
||||||
nutrition = NutritionInformationSerializer(allow_null=True, required=False)
|
nutrition = NutritionInformationSerializer(allow_null=True, required=False)
|
||||||
steps = StepSerializer(many=True)
|
steps = StepSerializer(many=True)
|
||||||
keywords = KeywordSerializer(many=True)
|
#keywords = KeywordSerializer(many=True)
|
||||||
rating = serializers.SerializerMethodField('get_recipe_rating')
|
|
||||||
last_cooked = serializers.SerializerMethodField('get_recipe_last_cooked')
|
|
||||||
shared = UserSerializer(many=True, required=False)
|
shared = UserSerializer(many=True, required=False)
|
||||||
|
rating = CustomDecimalField()
|
||||||
|
last_cooked = serializers.DateTimeField()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Recipe
|
model = Recipe
|
||||||
|
Reference in New Issue
Block a user