2016-10-25 3 views
0

나머지 프레임 워크에서 django를 사용하고 있습니다. 나는 ModelA 여부를 필터링 할 ModelAViewSetBooleanFilter을 추가하려면, 다음Django Rest 프레임 워크 OneToOneField 관련 BooleanFilter

class ModelAViewSet(viewsets.ModelViewSet): 
    queryset = ModelA.objects.all() 
    serializer_class = ModelASerializer 

:

class ModelA(models.Model): 
    pass 

class ModelB(models.Model): 
    a = models.OneToOneField(
     A, related_name='b') 

그리고 나는 뷰셋는 적용했다 :

는 지금은 OneToOne 관계로 모델을 가지고 개체에 관련이있는 ModelB 개체가 있습니다.

내가 아래 시도 : 작동하는지

class ModelAViewSet(viewsets.ModelViewSet): 
    class Filter(FilterSet): 
     has_b = filters.BooleanFilter('b') 
    queryset = ModelA.objects.all() 
    serializer_class = ModelASerializer 
    filter_fields = ['has_b'] 

그래서, 우리가 가진 :

  1. ?has_b=1 : 필터링없이 모든 레코드를 반환;
  2. ?has_b=2 : ModelA 개체와 관련된 레코드를 반환합니다.
  3. ?has_b=3 : 아니오가 인 레코드를 반환하는 중 ModelA 개체가 있음;

위의 경우 3을 제외하고는 거의 효과가있었습니다.

그럼 어떻게해야할까요?

+0

왜 부울 필터에 번호를 전달하는? – Sayse

+0

부울 결과가 아닌 관련 OneToOneField를 전달합니다. 쿼리 문자열을 만들어야 할 수도 있지만 솔루션을 찾을 수 있습니다. –

+0

@Sayse 기본 위젯은 django의 [NullBooleanSelect] (https://github.com/django/django/blob/1.10/django/forms/widgets.py#L561-L589)이며 이러한 선택 사항을 사용합니다. django-filter의 최신 버전을 사용한다면'django_filters.rest_framework import FilterSet, filters' 대신 다음을 할 수 있습니다. 서브 패키지의'BooleanFilter'는 커스텀'BooleanWidget'을 대신 사용합니다. – Sherpa

답변

1
from django_filters.rest_framework import FilterSet, filters 

class Filter(FilterSet): 
    has_b = filters.BooleanFilter(name='b', lookup_expr='isnull', exclude=True) 

여기에 세 가지 변화가 있습니다

  1. rest_framework 서브 패키지에서 가져 오기를함으로써 당신은 ?has_b=true 대신 ?has_b=1 조회 할 수 있도록하는 API 친화적 BooleanWidget는 사용이.

  2. 필터는 isnull 조회를 사용하여 관련 모델의 존재 여부를 테스트 할 수 있습니다.

  3. b__isnull=True당신이 원하는 것과 반대 인 관련 B 부족에 대한 테스트입니다. exclude=True을 사용하면 B이 대신 A의 필터가 대신 사용됩니다.

등가 .filter() 통화 :

# before, incorrect 
A.objects.filter(b=True) 

# after, correct 
A.objects.exclude(b__isnull=True) 
관련 문제