2016-10-25 23 views
0

私はrest-frameworkでdjangoを使用しています。Django RestフレームワークOneToOneField関連BooleanFilter

は、今私はOneToOne関係を搭載したモデルがあります:

class ModelA(models.Model): 
    pass 

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

をそして、私は上のビューセットを適用した。その後

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

、私はModelAかどうかをフィルタリングするModelAViewSetBooleanFilterを追加したいですオブジェクトには、関連する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の最新バージョンを使用している場合は、 'from 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) 

ここでは3つの変更があります。

  1. rest_frameworkサブパッケージからインポートすることで、あなたが?has_b=true代わりの?has_b=1を照会することができるので、APIに優しいBooleanWidgetは、使用されています。

  2. フィルタではisnullルックアップを使用しており、関連するモデルの存在をテストできます。 が何をしたいの反対である、関連Bが不足しているため

  3. b__isnull=Trueはテストです。 exclude=Trueを使用すると、その代わりに、関連するBが代わりにAにフィルタリングされるようにロジックが反転されます。

同等.filter()呼び出し:

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

# after, correct 
A.objects.exclude(b__isnull=True) 
関連する問題