Skip to content

fix: same type list #1492

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions graphene_django/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,20 @@

class DjangoListField(Field):
def __init__(self, _type, *args, **kwargs):
from .types import DjangoObjectType

if isinstance(_type, NonNull):
_type = _type.of_type

# Django would never return a Set of None vvvvvvv
super().__init__(List(NonNull(_type)), *args, **kwargs)

@property
def type(self):
from .types import DjangoObjectType

assert issubclass(
self._underlying_type, DjangoObjectType
), "DjangoListField only accepts DjangoObjectType types"
), "DjangoListField only accepts DjangoObjectType types as underlying type"
return super().type

@property
def _underlying_type(self):
Expand Down
3 changes: 3 additions & 0 deletions graphene_django/tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

class Person(models.Model):
name = models.CharField(max_length=30)
parent = models.ForeignKey(
"self", on_delete=models.CASCADE, null=True, blank=True, related_name="children"
)


class Pet(models.Model):
Expand Down
77 changes: 73 additions & 4 deletions graphene_django/tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,23 @@
Article as ArticleModel,
Film as FilmModel,
FilmDetails as FilmDetailsModel,
Person as PersonModel,
Reporter as ReporterModel,
)


class TestDjangoListField:
def test_only_django_object_types(self):
class TestType(ObjectType):
foo = String()
class Query(ObjectType):
something = DjangoListField(String)

with pytest.raises(TypeError) as excinfo:
Schema(query=Query)

with pytest.raises(AssertionError):
DjangoListField(TestType)
assert (
"Query fields cannot be resolved. DjangoListField only accepts DjangoObjectType types as underlying type"
in str(excinfo.value)
)

def test_only_import_paths(self):
list_field = DjangoListField("graphene_django.tests.schema.Human")
Expand Down Expand Up @@ -262,6 +268,69 @@ class Query(ObjectType):
]
}

def test_same_type_nested_list_field(self):
class Person(DjangoObjectType):
class Meta:
model = PersonModel
fields = ("name", "parent")

children = DjangoListField(lambda: Person)

class Query(ObjectType):
persons = DjangoListField(Person)

schema = Schema(query=Query)

query = """
query {
persons {
name
children {
name
}
}
}
"""

p1 = PersonModel.objects.create(name="Tara")
PersonModel.objects.create(name="Debra")

PersonModel.objects.create(
name="Toto",
parent=p1,
)
PersonModel.objects.create(
name="Tata",
parent=p1,
)

result = schema.execute(query)

assert not result.errors
assert result.data == {
"persons": [
{
"name": "Tara",
"children": [
{"name": "Toto"},
{"name": "Tata"},
],
},
{
"name": "Debra",
"children": [],
},
{
"name": "Toto",
"children": [],
},
{
"name": "Tata",
"children": [],
},
]
}

def test_get_queryset_filter(self):
class Reporter(DjangoObjectType):
class Meta:
Expand Down