Search code examples
djangographqlgraphene-django

Django relay filter not working for foreign key field


import graphene
from graphene_django import DjangoObjectType
from commodity.models import CommodityItem


class Brand(models.Model):
    # more fields...
    name = models.CharField(max_length=500)
    

class CommodityItem(models.Model):

    # more fields...
    is_online = models.BooleanField(default=True)
    brand = models.ForeignKey(
        Brand, on_delete=models.CASCADE, verbose_name='Brand', db_index=True)
        
        
class CommodityItemNode(DjangoObjectType):
    class Meta:
        model = CommodityItem
        use_connection = True
        description = 'Represents commodity item'
        filter_fields = {
            'is_online' : ['exact'],
            'brand_id': ['exact']
        }
        interfaces = (graphene.relay.Node, )
        
all_commodity_item = DjangoFilterConnectionField(CommodityItemNode)

Working

query {
    allCommodityItem(isOnline: true) {
        edges {
            node {
                name
            }
        }
    }
}

Not Working

query {
    allCommodityItem(isOnline: true, brandId: 1) {
        edges {
            node {
                name
            }
        }
    }
}

Error:

{
  "status": "error",
  "errors": [
    {
      "message": "['{\"brand_id\": [{\"message\": \"Invalid ID specified.\", \"code\": \"\"}]}']",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "allCommodityItem"
      ]
    }
  ],
  "data": {
    "allCommodityItem": null
  }
}

What I am missing here?

Reference: https://docs.graphene-python.org/projects/django/en/latest/tutorial-relay/


Solution

  • Add id as relation like this:

    class CommodityItemNode(DjangoObjectType):
        class Meta:
            # rest of code
            filter_fields = {
               'is_online' : ['exact'],
               'brand__id': ['exact']
            }
    

    And in your query:

    query {
        allCommodityItem(isOnline: true, brand_Id: "1") {
            edges {
               node {
                  name
               }
            }
        }
    }