Skip to content

Filter doesn't work with TextChoices field  #1541

Open
@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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions