我正在创建一个应用程序,其中食物具有多个组件,并且每个组件都具有特定值。 我希望能够过滤食物以获得特定成分的价值。
这是我的模特:
class Food(models.Model): id = models.AutoField(primary_key=True, db_column="id") name = models.CharField(max_length=150) product_type = models.CharField(max_length=150) class Component(models.Model): id = models.AutoField(primary_key=True, db_column="id") name = models.CharField(max_length=150) value = models.FloatField() food = models.ForeignKey(Food, related_name='food_components', related_query_name='food_components')然后我定义过滤器集和视图
import rest_framework_filters as filters class ComponentFilter(filters.FilterSet): name = filters.CharFilter(name="name") val = filters.NumberFilter(name="value", distinct=True) minval = filters.NumberFilter(name="value", lookup_type="gte", distinct=True) maxval = filters.NumberFilter(name="value", lookup_type="lte", distinct=True) class Meta: model = Component class FoodFilter(filters.FilterSet): name = filters.CharFilter(name='name') product_type = filters.CharFilter(name='product_type') components = filters.RelatedFilter(ComponentFilter, name='food_components') class Meta: model = Food class FoodViewSet(viewsets.ModelViewSet): queryset = Food.objects.all() serializer_class = FoodSerializer filter_class = FoodFilter我希望能够使用相关模型中的多个字段过滤视图集(组合这两个参数)。 像http:// whatever / foods / components__name = X&components__value = 1之类的东西会让我得到价值为1的元素X的所有食物。我正在使用django-rest-framework-filters( https://github.com/philipn/django -rest-framework-filters )
从我看到的,因为所有食物都含有所有元素,所以组件_name是无关紧要的,我会得到所有含有任何成分值的食物1.如何将两者结合起来?
提前致谢!
I am creating an application where food has several components, and each component has a specific value. I want to be able to filter food for the value of a specific component.
Here are my models:
class Food(models.Model): id = models.AutoField(primary_key=True, db_column="id") name = models.CharField(max_length=150) product_type = models.CharField(max_length=150) class Component(models.Model): id = models.AutoField(primary_key=True, db_column="id") name = models.CharField(max_length=150) value = models.FloatField() food = models.ForeignKey(Food, related_name='food_components', related_query_name='food_components')Then I define filter sets and the view
import rest_framework_filters as filters class ComponentFilter(filters.FilterSet): name = filters.CharFilter(name="name") val = filters.NumberFilter(name="value", distinct=True) minval = filters.NumberFilter(name="value", lookup_type="gte", distinct=True) maxval = filters.NumberFilter(name="value", lookup_type="lte", distinct=True) class Meta: model = Component class FoodFilter(filters.FilterSet): name = filters.CharFilter(name='name') product_type = filters.CharFilter(name='product_type') components = filters.RelatedFilter(ComponentFilter, name='food_components') class Meta: model = Food class FoodViewSet(viewsets.ModelViewSet): queryset = Food.objects.all() serializer_class = FoodSerializer filter_class = FoodFilterI want to be able to filter a viewset using more than one field in a related model (combining both parameters). Something like http://whatever/foods/components__name=X&components__value=1 would get me all foods with the element X of value 1. I am using django-rest-framework-filters (https://github.com/philipn/django-rest-framework-filters)
From what I see, since all foods have all the elements, the components__name is irrelevant, and I will get all the foods that have any component with the value 1. How can I combine both?
Thanks in advance!
最满意答案
您需要创建一个新的过滤器来处理与给定Component相关的单个 Food对象上的name , val对:
class FoodComponentFilter(django_filters.Filter): def filter(self, qs, value): strs = value.split(',') if len(strs) != 2: raise Exception return qs.filter( food_components__in = Component.objects.filter( name=strs[0], value=float(strs[1]) ) )在FoodFilter实例化:
class FoodFilter(filters.FilterSet): component_food_pair = FoodComponentFilter(name='dummy_field') [...] class Meta: model = Food fields = ('component_food_pair',[...])然后,使用它像:
?component_food_pair=Foo,42.0You'll need to create a new filter that handles the name, val pair on a single Food object that is related to a given Component:
class FoodComponentFilter(django_filters.Filter): def filter(self, qs, value): strs = value.split(',') if len(strs) != 2: raise Exception return qs.filter( food_components__in = Component.objects.filter( name=strs[0], value=float(strs[1]) ) )Instantiate this in the FoodFilter:
class FoodFilter(filters.FilterSet): component_food_pair = FoodComponentFilter(name='dummy_field') [...] class Meta: model = Food fields = ('component_food_pair',[...])Then, use it like:
?component_food_pair=Foo,42.0更多推荐
value,class,食物,filters,电脑培训,计算机培训,IT培训"/> <meta name="descri
发布评论