Пользовательский кверисет Django на основе django_filters.FilterSet
Я сделал django приложение для создания рецептов. Я хочу искать рецепты, в которых есть определенный ингредиент. Вот моя модель.
class Recipe(models.Model):
recipe_name = models.CharField(max_length=100)
recipe_category = models.ForeignKey('components.RecipeCategory', on_delete=models.CASCADE,related_name='recipe_category')
recipe_image = models.ImageField(blank=True, null=True, default="default.jpg", upload_to="recipe_pics/")
recipe_instructions = models.TextField(blank=True, null=True)
recipe_location = models.ForeignKey('components.RecipeBook', on_delete=models.CASCADE, related_name='recipe_location', blank=True, null=True)
location_page_number = models.IntegerField(blank=True, null=True)
ingredients = models.ManyToManyField('Ingredient', blank=True)
recipe_rating = models.CharField(blank=True, null=True, default='good', choices=RECIPE_RATING, max_length=50)
comments = models.TextField(blank=True, null=True)
class Ingredient(models.Model):
ingredient_name = models.ForeignKey('components.Food', on_delete=models.CASCADE, related_name='ingredient_name')
ingredient_quantity = models.FloatField()
quantity_unit = models.ForeignKey('components.MeasuringUnit', on_delete=models.CASCADE, related_name='quantity_unit')
class Food(models.Model):
food_name = models.CharField(max_length=100)
food_category = models.ForeignKey('FoodCategory', on_delete=models.CASCADE, related_name='food_category')
food_aisle = models.ForeignKey('Aisle', on_delete=models.CASCADE, related_name='food_aisle', blank=True, null=True, default=Aisle.get_default_pk)
Вот моя форма набора фильтров в данный момент. В настоящее время я выполняю поиск только по категории рецептов.
class RecipeFilter(django_filters.FilterSet):
# The below code changes the default filter label to "ALL"
recipe_category = django_filters.ModelChoiceFilter(queryset=RecipeCategory.objects.all(), empty_label="All")
Вот мое мнение
class RecipeFilterList(FilterView):
model = Recipe
filterset_class = RecipeFilter
context_object_name = 'recipes'
template_name = 'recipe_filter'
paginate_by = 10
def get_context_data(self, **kwargs):
kwargs['current_page'] = self.request.GET.get('page', 1)
return super().get_context_data(**kwargs)
Если я пытаюсь просто добавить ингредиенты к классу Meta в форме FilterSet, он отображает каждый объект 'Ingredient', что вполне логично. Это возвращает только один рецепт, который содержит именно этот объект Ingredient. Я же хочу получить набор запросов, который находит каждый ингредиент с выбранным названием блюда. Например, если я выберу "курица" в выпадающем меню, фильтр вернет все рецепты, содержащие курицу. Можно ли где-то применить приведенный ниже код и использовать кверисет Food.objects.all() в качестве параметра выбора?:
def custom_food_queryset(selection):
selection = form.cleaned_data.get('food_name')
query_list = []
for recipe in Recipe.objects.all():
for ingredient in recipe.ingredients.all():
if str(selection) == str(ingredient):
query_list.append(ingredient)
return querylist
Возможно, использование представления функции даст мне больше свободы для фильтрации данных? Любая помощь будет очень признательна. Заранее спасибо.