graphql-python / graphql-python/graphene-django

Filter doesn't work with TextChoices field

Open
#1,541 2 comments 0 reactions 0 assignees View on GitHub
🐛bug
Dominant language
Python
Stars
4.4k
Forks
760
PR merge metrics
No merged PRs in 30d

Description

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
```python
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

```python
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

```graphql
{
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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.