diff --git a/cookbook/helper/recipe_search.py b/cookbook/helper/recipe_search.py index 0704b206..df1426a4 100644 --- a/cookbook/helper/recipe_search.py +++ b/cookbook/helper/recipe_search.py @@ -1,3 +1,4 @@ +import json from collections import Counter from datetime import timedelta @@ -12,7 +13,7 @@ from cookbook.filters import RecipeFilter from cookbook.helper.HelperFunctions import Round, str2bool from cookbook.helper.permission_helper import has_group_permission from cookbook.managers import DICTIONARY -from cookbook.models import CookLog, Food, Keyword, Recipe, SearchPreference, ViewLog +from cookbook.models import CookLog, CustomFilter, Food, Keyword, Recipe, SearchPreference, ViewLog from recipes import settings @@ -24,7 +25,14 @@ class RecipeSearch(): def __init__(self, request, **params): self._request = request self._queryset = None - self._params = {**params} + if filter := params.get('filter', None): + try: + self._params = {**json.loads(CustomFilter.objects.get(id=filter).search)} + except CustomFilter.DoesNotExist: + self._params = {**(params or {})} + else: + self._params = {**(params or {})} + self._query = self._params.get('query', {}) or {} if self._request.user.is_authenticated: self._search_prefs = request.user.searchpreference else: @@ -53,12 +61,11 @@ class RecipeSearch(): self._units = self._params.get('units', None) # TODO add created by # TODO image exists - self._sort_order = self._params.get('sort_order', None) - self._books_or = str2bool(self._params.get('books_or', True)) + self._sort_order = self._params.get('sort_order', None) or self._query.get('sort_order', 0) self._internal = str2bool(self._params.get('internal', False)) self._random = str2bool(self._params.get('random', False)) self._new = str2bool(self._params.get('new', False)) - self._last_viewed = int(self._params.get('last_viewed', 0)) + self._last_viewed = int(self._params.get('last_viewed', 0) or self._query.get('last_viewed', 0)) self._timescooked = self._params.get('timescooked', None) self._lastcooked = self._params.get('lastcooked', None) self._makenow = self._params.get('makenow', None) diff --git a/cookbook/migrations/0168_auto_20220121_1427.py b/cookbook/migrations/0168_auto_20220121_1427.py index 733ef8b4..67b13e32 100644 --- a/cookbook/migrations/0168_auto_20220121_1427.py +++ b/cookbook/migrations/0168_auto_20220121_1427.py @@ -33,4 +33,9 @@ class Migration(migrations.Migration): model_name='customfilter', constraint=models.UniqueConstraint(fields=('space', 'name'), name='cf_unique_name_per_space'), ), + migrations.AddField( + model_name='recipebook', + name='filter', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='cookbook.customfilter'), + ), ] diff --git a/cookbook/models.py b/cookbook/models.py index db6df086..8b913c90 100644 --- a/cookbook/models.py +++ b/cookbook/models.py @@ -725,6 +725,7 @@ class RecipeBook(ExportModelOperationsMixin('book'), models.Model, PermissionMod icon = models.CharField(max_length=16, blank=True, null=True) shared = models.ManyToManyField(User, blank=True, related_name='shared_with') created_by = models.ForeignKey(User, on_delete=models.CASCADE) + filter = models.ForeignKey('cookbook.CustomFilter', null=True, blank=True, on_delete=models.SET_NULL) space = models.ForeignKey(Space, on_delete=models.CASCADE) objects = ScopedManager(space='space') diff --git a/cookbook/serializer.py b/cookbook/serializer.py index f4fe8261..a269b372 100644 --- a/cookbook/serializer.py +++ b/cookbook/serializer.py @@ -604,8 +604,22 @@ class CommentSerializer(serializers.ModelSerializer): fields = '__all__' +class CustomFilterSerializer(SpacedModelSerializer, WritableNestedModelSerializer): + shared = UserNameSerializer(many=True, required=False) + + def create(self, validated_data): + validated_data['created_by'] = self.context['request'].user + return super().create(validated_data) + + class Meta: + model = CustomFilter + fields = ('id', 'name', 'search', 'shared', 'created_by') + read_only_fields = ('created_by',) + + class RecipeBookSerializer(SpacedModelSerializer, WritableNestedModelSerializer): shared = UserNameSerializer(many=True) + filter = CustomFilterSerializer(required=False) def create(self, validated_data): validated_data['created_by'] = self.context['request'].user @@ -613,8 +627,8 @@ class RecipeBookSerializer(SpacedModelSerializer, WritableNestedModelSerializer) class Meta: model = RecipeBook - fields = ('id', 'name', 'description', 'icon', 'shared', 'created_by') - read_only_fields = ('created_by',) + fields = ('id', 'name', 'description', 'icon', 'shared', 'created_by', 'filter') + read_only_fields = ('created_by', ) class RecipeBookEntrySerializer(serializers.ModelSerializer): @@ -976,16 +990,3 @@ class FoodShoppingUpdateSerializer(serializers.ModelSerializer): class Meta: model = Recipe fields = ['id', 'amount', 'unit', 'delete', ] - - -class CustomFilterSerializer(SpacedModelSerializer, WritableNestedModelSerializer): - shared = UserNameSerializer(many=True, required=False) - - def create(self, validated_data): - validated_data['created_by'] = self.context['request'].user - return super().create(validated_data) - - class Meta: - model = CustomFilter - fields = ('id', 'name', 'search', 'shared', 'created_by') - read_only_fields = ('created_by',) diff --git a/cookbook/views/api.py b/cookbook/views/api.py index 832293e9..5dd5bfed 100644 --- a/cookbook/views/api.py +++ b/cookbook/views/api.py @@ -526,7 +526,6 @@ class RecipeBookEntryViewSet(viewsets.ModelViewSet, viewsets.GenericViewSet): book_id = self.request.query_params.get('book', None) if book_id is not None: queryset = queryset.filter(book__pk=book_id) - return queryset @@ -669,8 +668,10 @@ class RecipeViewSet(viewsets.ModelViewSet): if not (share and self.detail): self.queryset = self.queryset.filter(space=self.request.space) - # self.queryset = search_recipes(self.request, self.queryset, self.request.GET) - params = {x: self.request.GET.get(x) if len({**self.request.GET}[x]) == 1 else self.request.GET.getlist(x) for x in list(self.request.GET)} + if filter := (self.request.GET.get('query', {}) or {}).get('filter', None): + params = {'filter': filter} + else: + params = {x: self.request.GET.get(x) if len({**self.request.GET}[x]) == 1 else self.request.GET.getlist(x) for x in list(self.request.GET)} search = RecipeSearch(self.request, **params) self.queryset = search.get_queryset(self.queryset).prefetch_related('cooklog_set') return self.queryset diff --git a/vue/src/apps/CookbookView/CookbookView.vue b/vue/src/apps/CookbookView/CookbookView.vue index 6363c52f..bcdb7004 100644 --- a/vue/src/apps/CookbookView/CookbookView.vue +++ b/vue/src/apps/CookbookView/CookbookView.vue @@ -6,11 +6,7 @@