2017-09-18 3 views
0

Caractéristiques:
django == 1.11.5
djangorestframework == 3.6.4
PostgreSQL 9.6.5 sur x86_64-pomme-darwin14.5.0, compilé par la version d'Apple LLVM 7.0.0 (clang-700.1.76), 64-bit
python 3.6.2
DRF Recherche sur ArrayField

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', 
    ) 

Références: https://groups.google.com/forum/#!topic/django-filter/ns7zx1C8HN8

AS IS: je dois rechercher le nombre exact de téléphone match ce client.
Par exemple customer.phones = ['024382426', '024387269']
Je dois filtrer avec 024382426 pour obtenir ce customers.

Question: Comment faire mettre le numéro de téléphone en bref comme 438 et obtenir que customer?

Répondre

1

ArrayField est en fait une liste . Et pour la recherche de liste, le mot-clé en est utilisé. Vous utilisez contient, et c'est pour CharField. Vous devez mettre en comme lookup_expr comme ceci:

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', 
    ) 

Et pour Arrayfield, vous avez besoin NumberFilter à la place de CharFilter. Mise à jour aussi, s'il vous plaît vérifier.

+0

'' 'opérateur n'existe pas: caractère variable [] = text [] LIGNE 1: ... ers_customer » OÙ "customers_customer téléphones "IN (ARRAY [... ^ HINT".": Aucun opérateur correspond au type donné et au (x) type (s) d'argument.Vous devrez peut-être ajouter un type explicite cast.''' – Sarit

+0

@Sarit Okay, va regarder dans l'erreur –

+0

@Sarit Ceci est une erreur PostgreSQL, vous comparez des entiers avec varchar ou Veuillez faire en sorte que le champ de recherche et le champ clé soient cohérents l'un par rapport à l'autre –