Django过滤子对象的值

时间:2017-03-01 08:26:28

标签: python django django-filter

我有以下(简化)数据模型:

class Article(Model):
    uuid = models.CharField(primary_key=True, max_length=128)

class Attribute(Model):
    uuid = models.CharField(primary_key=True, max_length=128)
    article = models.ForeignKey(Article, related_name='attributes')
    type = models.CharField(max_length=256)
    value = models.CharField(max_length=256)

示例用法是使用type="brand"value="Nike"附加了属性的文章。现在我想写一个API,它可以获得具有某个品牌的所有文章,但我似乎无法为其编写过滤器。这就是我到目前为止所做的:

class PhotobookFilter(df.FilterSet):
    brand = df.CharFilter(method='filter_brand')

    class Meta:
        model = Article

    def filter_brand(self, queryset, name, value):
        return queryset.filter('order__attributes')

class PhotobookViewSet(AbstractOrderWriterViewSet):
    queryset = Article.objects.all()
    serializer_class = ArticlePhotobookSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_class = PhotobookFilter

queryset.filter行明显不正确。我需要在此处创建一个过滤器,该过滤器返回包含type="brand"value=value属性的所有文章。我该怎么做?

3 个答案:

答案 0 :(得分:1)

您确定要将查询(type的{​​{1}}和value)压缩到一个过滤器中吗?为什么不允许分别对这两个字段进行过滤?

E.g。

Attribute

现在像class PhotobookFilter(df.FilterSet): type = df.CharFilter(method='filter_type') value = df.CharFilter(method='filter_value') class Meta: model = Article def filter_type(self, queryset, name, value): return queryset.filter(**{'attributes__type': value}) def filter_value(self, queryset, name, value): return queryset.filter(**{'attributes__value': value}) 这样的查询应该有效。

显然,你可以将这两个条件压缩成一个过滤器,例如硬编码乐队部分:

?type=brand&value=Nike

但保持它们分开感觉更灵活。

答案 1 :(得分:1)

你也可以像这样过滤:

class PhotobookFilter(df.FilterSet):
    brand = df.CharFilter(method='filter_brand')

    class Meta:
        model = Article

    def filter_brand(self, queryset, name, value):
        articles = Attribute.objects.filter(type="brand", value=value).values_list('article_id', flat=True)
        return queryset.filter(id__in=articles)

这将为Attribute创建子查询,最终仍然是一个SQL请求

答案 2 :(得分:0)

使用search_fields。要获得正确的结果,请重命名“类型”属性名称http://www.codesend.com/view/09ca65d42248fe1d89d07ce151f4f050/