2017-09-15 80 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 

哪一個可以正常工作。
但是,我想提供一個自定義的查詢集到模型過濾器,以便我可以在字段上執行聚合。我試圖做這樣的事情:

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 

檢查GraphiQL中的原始SQL,它看起來是正確的。但是,我從GraphQL收到錯誤消息是

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

這是正確的結果,但我不能確定爲什麼GraphQL正從Django的石墨烯此對象。我如何提供自定義查詢集並使其工作?

回答

1

看起來django-graphene正在期待模型實例的QuerySet,當您在QuerySet上調用.values()時,您將獲取字典的查詢集,因此將獲得Received incompatible instance

您可能可以使用subquery expressions或做一些rawsql queries這兩者都會返回模型實例,它實際上取決於您在模型上設置的關係的類型。

從關係的另一端(客戶端)看起來似乎更容易做這個註釋,因爲您不需要使用.values(),但它可能無法滿足您的需求。

+0

感謝您的回覆。我採取刺傷.raw(),但返回一個RawQuerySet和Django石墨烯和Django過濾器真的想要一個QuerySet。它炸彈是因爲RawQuerySet沒有使用django-filter嘗試調用結果的.all()方法。 – duffn

1

我假設你的問題發生是因爲.values()返回一個字典而不是一個模型實例。

你可以儘量避免的.values()的使用,你可以在aggregation cheat sheet的最後兩個例子,在Generate aggregates for each item in a QuerySet部分中看到:

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 

但請記住,你將不得不調整自己的「前端」/接收器因爲現在您的解析器將返回一個查詢集而不是字典。

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,看看有沒有其他的工作你也可以嘗試從DjangoConnectionFieldrelay.connection