2017-09-15 43 views
9

django-filterを使ってdjango-grapheneのリゾルバでフィールドを集計したいと思います。通常、私のリゾルバは次のようになります:django-grapheneとフィルタに注釈を付ける

my_model = DjangoFilterConnectionField(
     MyModelNode, 
     filterset_class=MyModelFilter) 

def my_resolver(self, args, context, info): 

    return MyModelFilter(
     data=format_query_args(args), 
     queryset=self).qs 

これはうまくいきます。
しかし、フィールドに集計を実行できるように、モデルフィルタにカスタムクエリーセットを提供したいと思います。 GraphiQLで生のSQLを点検

def my_resolver(self, args, context, info): 
    queryset = MyModel.objects.values(
     'customer_id').annotate(
     cost_amt=Sum('cost_amt', output_field=FloatField())) 

    return MyModelFilter(
     data=format_query_args(args), 
     queryset=queryset).qs 

、それが正しいになります。私はこのような何かをしようとしています。しかし、私はGraphQLから受け取るエラーメッセージが

"message": "Received incompatible instance \"{'cost_amt': 260.36, 'customer_id': 300968697}\"." 

これは正しい結果であるが、GraphQLはジャンゴ-グラフェンからこのオブジェクトを取得しているなぜ私はわかりませんよ。カスタムクエリーセットを提供してこの作業を行うにはどうすればよいですか?

答えて

1

django-grapheneがモデルインスタンスのQuerySetを期待しているようですが、.values()をQuerySetで呼び出すと、辞書のクエリセットが返されるので、Received incompatible instanceとなります。

subquery expressionsを使用するか、rawsql queriesを実行すると、両方ともモデルインスタンスが返されます。モデルに設定されている関係の種類によって異なります。

.values()を使用する必要がないため、この注釈を関係の他端(顧客側)から行う方が簡単かもしれないようですが、必要なものでは機能しない可能性があります。

+0

お返事ありがとうございます。私は.raw()でスタブを取ったが、それはRawQuerySetを返し、django-grapheneとdjango-filterは本当にQuerySetを必要とする。 RawQuerySetには、django-filterが結果を呼び出そうとする.all()メソッドを持たないため、爆発します。 – duffn

1

.values()がモデルインスタンスではなく辞書を返すため、問題が発生したと想定します。

def my_resolver(self, args, context, info): 
    queryset = MyModel.objects.annotate(
     cost_amt=Sum('cost_amt', output_field=FloatField())) 

return MyModelFilter(
    data=format_query_args(args), 
    queryset=queryset).qs 

しかし、あなたはあなたのを調整する必要があることに注意してください:あなたはaggregation cheat sheetの最後の2つの例ではとGenerate aggregates for each item in a QuerySetセクションで見ることができるよう

あなたは.values()の使用を回避しようとすることができます"フロントエンド" /レシーバこれは、リゾルバが辞書ではなくクエリーセットを返すようになるためです。クエリセットのために

2

あなたは

queryset = MyModel.objects.annotate(cost_amt=Sum('cost_amt', output_field=FloatField())) 

を使用して取得することができますが、モデルのインスタンスを取得する必要が動作するようにして、あなたはさらにアクションを試すことができます。

return MyModelFilter(data=format_query_args(args),queryset=queryset).qs 

まだASSET UNIONを試してみて、それが他に動作するかどうかあなたもrelay.connectionからDjangoConnectionFieldを試すことができます参照してください

をエラー。

関連する問題