Skip to content

Filter doesn't work with TextChoices field  #1541

@janeliutw

Description

@janeliutw

I have been trying to get the filter works but have not been able to, I think I found a bug, here's what I have:

models.py

class Document(models.Model):
    name = models.CharField(
        max_length=256,
        unique=True,
    )
    
    class DocumentType(models.TextChoices):
        OTHER = "other", "Other"
        REPORT = "report", "Report"
        WORKSHEET = "worksheet", "Worksheet"

    document_type = models.CharField(
        choices=DocumentType.choices,
        default=DocumentType.REPORT,
        max_length=32,
    )

schema.py

from django_filters import FilterSet

class DocumentFilter(FilterSet):
    class Meta:
        model = Document
        fields = {
            "document_type": ["exact", "startswith"],
            "name": ["exact", "iexact", "contains", "icontains"],
        }
        
class DocumentType(DjangoObjectType):
    class Meta:
        model = Document
        interfaces = (relay.Node,)
        connection_class = CountableConnection
        filterset_class = DocumentFilter
 
class Query(ObjectType):
    documents = DjangoFilterConnectionField(
        DocumentType,
        orderBy=List(of_type=String),
    )
  • What is the current behavior?

Here's my query

{
  documents(documentType: WORKSHEET) {
    edges {
      node {
        name
        documentType
      }
    }
  }
  _debug {
    sql {
      sql
      duration
    }
  }
}

it returns all the documents without filtering (see there's no WHERE clause in the returned sql)

{
  "data": {
    "documents": {
      "edges": [
        {
          "node": {
            "name": "Disease Status Worksheet (Validated v. Candidate)",
            "documentType": "WORKSHEET"
          }
        },
        {
          "node": {
            "name": "Mechanism of Disease Worksheet (LOF)",
            "documentType": "WORKSHEET"
          }
        },
        {
          "node": {
            "name": "Episode 5 Inheritance in GeneMb Definitions",
            "documentType": "OTHER"
          }
        },
      ]
    },
    "_debug": {
      "sql": [
        {
          "sql": "SELECT COUNT(*) AS \"__count\" FROM \"documents_document\"",
          "duration": 0.0032892227172851562
        },
        {
          "sql": "SELECT \"documents_document\".\"id\", \"documents_document\".\"document_id\", \"documents_document\".\"name\", \"documents_document\".\"description\", \"documents_document\".\"document_type\", \"documents_document\".\"last_modified_on\", \"documents_document\".\"last_modified_by_id\" FROM \"documents_document\" ORDER BY \"documents_document\".\"id\" ASC LIMIT 10",
          "duration": 0.005330085754394531
        }

If I use "startswith" in the query:

{
  documents(documentType_Startswith: WORKSHEET) {
    edges {
      node {
        name
        documentType
      }
    }
  }
  _debug {
    sql {
      sql
      duration
    }
  }
}

and it returned nothing but in the sql it's using the enum directly in the WHERE clause (i.e. DocumentsDocumentDocumentTypeChoices.WORKSHEET) rather than a string.

{
  "data": {
    "documents": {
      "edges": []
    },
    "_debug": {
      "sql": [
        {
          "sql": "SELECT COUNT(*) AS \"__count\" FROM \"documents_document\" WHERE \"documents_document\".\"document_type\"::text LIKE 'DocumentsDocumentDocumentTypeChoices.WORKSHEET%'",
          "duration": 0.003654956817626953
        }
      ]
    }
  }
}
  • What is the expected behavior?

It should use the value of the TextChoices field in the sql for filtering (e.g. "worksheet" in my example)

  • Please tell us about your environment:

Python 3.12
Django==5.1.4
graphene-django==3.2.2
django-filter==24.3
djangorestframework==3.15.2

  • Notes
    If I set "DJANGO_CHOICE_FIELD_ENUM_CONVERT": False in my settings.py then the filter works but I prefer to work with Enum.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions