Django Rest Framework - 过滤 ArrayField 包含 value1 或 value2 而不是子集的模型
Django Rest Framework - filters models where ArrayField includes value1 OR value2, not subset
开门见山。
这是我的模型:
class Product(models.Model):
brand = models.CharField(max_length=40)
model = models.CharField(max_length=40)
price = models.FloatField(default=0)
colors = ArrayField(models.CharField(max_length=20), blank=True, null=True, default=[])
sizes = ArrayField(models.IntegerField(), blank=True, null=True)
discount_price = models.FloatField(null=True, blank=True, default=list)
date_added = models.DateTimeField(auto_now_add=True)
desc = models.TextField(default=None, blank=True, null=True)
gender = models.CharField(choices=GENDER_CHOICES, blank=True, null=True, max_length=10)
for_kids = models.BooleanField(blank=True, null=True)
序列化器:
class ProductsSerializer(serializers.ModelSerializer):
pictures = ProductPicturesSerializer(many=True, read_only=True)
average_rating = serializers.SerializerMethodField()
def get_average_rating(self, obj):
return obj.average_rating
class Meta:
model = Product
fields = ['id', 'brand', 'model', 'price', 'discount_price',
'date_added', 'for_kids', 'gender',
'average_rating', 'sizes', 'colors', 'pictures']
我的自定义过滤器:
class CharArrayFilter(filters.BaseCSVFilter, filters.CharFilter):
pass
class ProductsFilter(filters.FilterSet):
min_price = filters.NumberFilter(field_name="price", lookup_expr='gte')
max_price = filters.NumberFilter(field_name="price", lookup_expr='lte')
colors = CharArrayFilter(lookup_expr='contains')
class Meta:
model = Product
fields = {
'brand': ['in'],
'model': ['in', 'exact'],
}
问题是,当我用红色、黑色、蓝色等颜色过滤它时,它只显示数组中具有这些值子集的对象,而不是我的目标之一。我找不到任何可行的查找表达式,如果有人想知道,尝试 lookup_expr = colors__in 也不起作用。
喜欢在此字段中显示所有值为 red OR black OR blue 的鞋子。
请帮忙,我什么都试过了
overlap
是您要查找的表达式。
Returns objects where the data shares any results with the values
passed. Uses the SQL operator &&. For example:
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
>>> Post.objects.filter(tags__overlap=['thoughts'])
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__overlap=['thoughts', 'tutorial'])
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
开门见山。
这是我的模型:
class Product(models.Model):
brand = models.CharField(max_length=40)
model = models.CharField(max_length=40)
price = models.FloatField(default=0)
colors = ArrayField(models.CharField(max_length=20), blank=True, null=True, default=[])
sizes = ArrayField(models.IntegerField(), blank=True, null=True)
discount_price = models.FloatField(null=True, blank=True, default=list)
date_added = models.DateTimeField(auto_now_add=True)
desc = models.TextField(default=None, blank=True, null=True)
gender = models.CharField(choices=GENDER_CHOICES, blank=True, null=True, max_length=10)
for_kids = models.BooleanField(blank=True, null=True)
序列化器:
class ProductsSerializer(serializers.ModelSerializer):
pictures = ProductPicturesSerializer(many=True, read_only=True)
average_rating = serializers.SerializerMethodField()
def get_average_rating(self, obj):
return obj.average_rating
class Meta:
model = Product
fields = ['id', 'brand', 'model', 'price', 'discount_price',
'date_added', 'for_kids', 'gender',
'average_rating', 'sizes', 'colors', 'pictures']
我的自定义过滤器:
class CharArrayFilter(filters.BaseCSVFilter, filters.CharFilter):
pass
class ProductsFilter(filters.FilterSet):
min_price = filters.NumberFilter(field_name="price", lookup_expr='gte')
max_price = filters.NumberFilter(field_name="price", lookup_expr='lte')
colors = CharArrayFilter(lookup_expr='contains')
class Meta:
model = Product
fields = {
'brand': ['in'],
'model': ['in', 'exact'],
}
问题是,当我用红色、黑色、蓝色等颜色过滤它时,它只显示数组中具有这些值子集的对象,而不是我的目标之一。我找不到任何可行的查找表达式,如果有人想知道,尝试 lookup_expr = colors__in 也不起作用。 喜欢在此字段中显示所有值为 red OR black OR blue 的鞋子。
请帮忙,我什么都试过了
overlap
是您要查找的表达式。
Returns objects where the data shares any results with the values passed. Uses the SQL operator &&. For example:
>>> Post.objects.create(name='First post', tags=['thoughts', 'django']) >>> Post.objects.create(name='Second post', tags=['thoughts']) >>> Post.objects.create(name='Third post', tags=['tutorial', 'django']) >>> Post.objects.filter(tags__overlap=['thoughts']) <QuerySet [<Post: First post>, <Post: Second post>]> >>> Post.objects.filter(tags__overlap=['thoughts', 'tutorial']) <QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>