400 Bad Request в клиенте Apollo, запрашивающем Django Backend

При попытке выполнить GraphQL-запрос с помощью Apollo Client в моем React frontend из Django/Django Rest/Graphene Backend я получаю следующую ошибку. Я также получаю некоторые ошибки CORS, поэтому я отключил cors на клиенте с:

fetchOptions: {
        mode: "no-cors",
      },

и на бэкенде с csrf_exempt.

Мне удается заставить запрос работать в Postman и GraphiQL, но не в React.

Вот мой запрос:

export const STOCKS_BY_ADJ_CLOSE_RANGE_AND_DATE_QUERY = gql`
  query StocksByAdjCloseRangeAndDate {
    stocksByAdjCloseRangeAndDate(
      low: 100
      high: 105
      start: "2024-03-01T00:00:00Z"
      end: "2024-03-10T00:00:00Z"
    ) {
      ticker
      datetime
      open
      high
      low
      close
      adjClose
      volume
    }
  }
`;

Вот мой клиент:

const errorLink = onError(({ graphQLErrors, networkError }) => {
  if (graphQLErrors) {
    console.log("graphQLErrors", graphQLErrors);
  }
  if (networkError) {
    console.log("networkError", networkError);
  }
});

const client = new ApolloClient({
  cache: new InMemoryCache(),
  headers: {
    "Content-Type": "application/json",
    "Access-Control-Allow-Origin": "*",
  },
  connectToDevTools: true,
  link: from([
    errorLink,
    new HttpLink({
      uri: "http://127.0.0.1:8000/graphql",
      fetchOptions: {
        mode: "no-cors",
      },
      headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Credentials": "true",
      },
    }),
  ]),
});

Вот мои маршруты Django:

urlpatterns = [
    # path("", router.urls),
    # path("", include(router.urls)),
    path(
        "api-auth/", include("rest_framework.urls", namespace="rest_framework")
    ),
    path("admin/", admin.site.urls),
    # path("", TemplateView.as_view(template_name="frontend/build/index.html")),
    path("api/", include(router.urls)),
    path("", home),
    path(
        r"graphql",
        csrf_exempt(GraphQLView.as_view(graphiql=True, schema=schema)),
    ),
]

Вот мои определения схемы бэкенда

class StockNode(DjangoObjectType):
    class Meta:
        model = Stock
        filter_fields = ["ticker"]
        interfaces = (relay.Node,)


class StockModelType(DjangoObjectType):
    class Meta:
        model = Stock


class Query(graphene.ObjectType):
    stocks = DjangoFilterConnectionField(StockNode)
    first_stock = graphene.List(StockNode, ticker=graphene.String())
    stocks_by_ticker = graphene.List(StockNode, ticker=graphene.String())
    stocks_by_datetime = graphene.List(
        StockNode, start=graphene.DateTime(), end=graphene.DateTime()
    )
    stocks_by_adj_close_range = graphene.List(
        StockNode, low=graphene.Float(), high=graphene.Float()
    )
    stocks_by_adj_close_range_and_date = graphene.List(
        StockNode,
        low=graphene.Float(),
        high=graphene.Float(),
        start=graphene.DateTime(),
        end=graphene.DateTime(),
    )

    def resolve_first_stock(self, info):
        return Stock.objects.first()

    def resolve_stocks(self, info):
        return Stock.objects.all()

    def resolve_stocks_by_ticker(self, info, ticker: str):
        return Stock.objects.filter(ticker=ticker)

    def resolve_stocks_by_datetime(self, info, start: str, end: str):
        return Stock.objects.filter(
            datetime__gte=start, datetime__lte=end
        ).distinct()

    def resolve_stocks_by_adj_close_range(self, info, low: float, high: float):
        return Stock.objects.filter(
            adj_close__gte=low, adj_close__lte=high
        ).distinct()

    def resolve_stocks_by_adj_close_range_and_date(
        self, info, low: float, high: float, start: str, end: str
    ):
        return (
            Stock.objects.filter(adj_close__gte=low, adj_close__lte=high)
            .distinct()
            .filter(datetime__gte=start, datetime__lte=end)
        ).distinct()


schema = graphene.Schema(query=Query)

Может ли кто-нибудь указать мне правильное направление? Я в растерянности, почему это будет работать везде, кроме React. :(

)
Вернуться на верх