如何在DRF中使用Django的filter_fields和ArrayField?

10

我在我的模型中使用了一个Postgres ArrayField。我尝试使用Django过滤器,但是我遇到了一个错误。

AutoFilterSet将字段“flavor”解析为“exact”查找并识别不了ArrayField字段类型。尝试向'Meta.filter_overrides'添加重写。参见:https://django-filter.readthedocs.io/en/master/ref/filterset.html#customise-filter-generation-with-filter-overrides

模型

class Items(models.Model):
    item = models.CharField(max_length=150, unique=True)
    matches = ArrayField(models.CharField(
        max_length=200), blank=True, default=list)
    category = ArrayField(models.CharField(
        max_length=200), blank=True, default=list)
    flavor = ArrayField(models.CharField(
        max_length=200), blank=True, default=list)
    special = ArrayField(models.CharField(
        max_length=200), blank=True, default=list)
    created_at = models.DateTimeField(auto_now_add=True)

视图集

class CategoryViewSet(viewsets.ModelViewSet):
    queryset = Items.objects.all()
    serializer_class = CategorySerializer
    filter_fields = ('item', 'category')
2个回答

12

好的,我搞清楚了,哈哈。需要使用lookup_exp='icontains'创建自定义过滤器。

class CategoryFilter(filters.FilterSet):
    category = filters.CharFilter(lookup_expr='icontains')

    class Meta:
        model = Items
        fields = ('item', 'category')
class CategoryViewSet(viewsets.ModelViewSet):
    queryset = Items.objects.all()
    serializer_class = CategorySerializer
    filterset_class = CategoryFilter

这里的'CategorySerializer'是什么? - varisha15
赞同了这个回答,但是如果没有 filter_backends = (filters.DjangoFilterBackend,) 这一行代码的话,它是无法正常工作的。 - Sardar Faisal

0
如果你想为ArrayField实现一些特定的查找功能,可以尝试这样做:
from django.contrib.postgres.forms.array import SimpleArrayField
from django_filters.filters import Filter

class ArrayOverlapFilter(Filter):
    field_class = SimpleArrayField

  def __init__(self, *args, **kwargs):
      kwargs.setdefault("lookup_expr", "overlap")
      super().__init__(*args, **kwargs)

在定义FilterSet时,您必须指定base_field。
devices = ArrayOverlapFilter(base_field=CharField())

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接