在ArrayField上搜索DRF

时间:2017-09-18 04:16:49

标签: python django django-rest-framework

规格:
Django的== 1.11.5
djangorestframework == 3.6.4
在x86_64-apple-darwin14.5.0上的PostgreSQL 9.6.5,由Apple LLVM版本7.0.0(clang-700.1.76)编译,64位
Python 3.6.2

models.py

from django.contrib.postgres.fields import ArrayField
from django.db import models
from djchoices import DjangoChoices, ChoiceItem


class Customer(models.Model):
    ...
    phones = ArrayField(models.CharField(max_length=30))

filters.py

import django_filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import FilterSet
from rest_framework.viewsets import ModelViewSet

from soken_web.apps.customers.api.serializers import CustomerSerializer
from soken_web.apps.customers.models import Customer


class CharInFilter(django_filters.BaseInFilter, django_filters.CharFilter):
    pass


class CustomerFilter(FilterSet):
    phones = CharInFilter(name='phones', lookup_expr='contains')

    class Meta:
        model = Customer
        fields = (
            ...,
            'phones',
        )


class CustomerViewset(ModelViewSet):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_class = CustomerFilter
    filter_fields = (
        ...
        'phones',
    )

参考文献: https://groups.google.com/forum/#!topic/django-filter/ns7zx1C8HN8

原样: 我必须搜索该客户的确切匹配电话号码 例如customer.phones = ['024382426', '024387269']
我必须使用024382426过滤才能获得customers

问题: 如何将电话号码简称为438并获取customer

1 个答案:

答案 0 :(得分:1)

ArrayField实际上是列表。对于列表查找,使用 in 关键字。您正在使用包含,这适用于CharField。 您需要将置于中作为 lookup_expr ,如下所示:

import django_filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import FilterSet
from rest_framework.viewsets import ModelViewSet

from soken_web.apps.customers.api.serializers import CustomerSerializer
from soken_web.apps.customers.models import Customer


class NumberInFilter(django_filters.BaseInFilter, django_filters.NumberFilter):
    pass


class CustomerFilter(FilterSet):
    phones = NumberInFilter(name='phones', lookup_expr='in')

    class Meta:
        model = Customer
        fields = (
            ...,
            'phones',
        )


class CustomerViewset(ModelViewSet):
    queryset = Customer.objects.all()
    serializer_class = CustomerSerializer
    filter_backends = (DjangoFilterBackend,)
    filter_class = CustomerFilter
    filter_fields = (
        ...
        'phones',
    )

对于Arrayfield,您需要 NumberFilter 代替 CharFilter 。也更新了这个,请检查。