fix: same type list (#1492)

* fix: same type list

* chore: improve test
This commit is contained in:
Laurent 2024-01-20 09:36:00 +01:00 committed by GitHub
parent 4d0484f312
commit b85177cebf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 82 additions and 7 deletions

View File

@ -20,17 +20,20 @@ from .utils import maybe_queryset
class DjangoListField(Field): class DjangoListField(Field):
def __init__(self, _type, *args, **kwargs): def __init__(self, _type, *args, **kwargs):
from .types import DjangoObjectType
if isinstance(_type, NonNull): if isinstance(_type, NonNull):
_type = _type.of_type _type = _type.of_type
# Django would never return a Set of None vvvvvvv # Django would never return a Set of None vvvvvvv
super().__init__(List(NonNull(_type)), *args, **kwargs) super().__init__(List(NonNull(_type)), *args, **kwargs)
@property
def type(self):
from .types import DjangoObjectType
assert issubclass( assert issubclass(
self._underlying_type, DjangoObjectType self._underlying_type, DjangoObjectType
), "DjangoListField only accepts DjangoObjectType types" ), "DjangoListField only accepts DjangoObjectType types as underlying type"
return super().type
@property @property
def _underlying_type(self): def _underlying_type(self):

View File

@ -6,6 +6,9 @@ CHOICES = ((1, "this"), (2, _("that")))
class Person(models.Model): class Person(models.Model):
name = models.CharField(max_length=30) 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): class Pet(models.Model):

View File

@ -12,17 +12,23 @@ from .models import (
Article as ArticleModel, Article as ArticleModel,
Film as FilmModel, Film as FilmModel,
FilmDetails as FilmDetailsModel, FilmDetails as FilmDetailsModel,
Person as PersonModel,
Reporter as ReporterModel, Reporter as ReporterModel,
) )
class TestDjangoListField: class TestDjangoListField:
def test_only_django_object_types(self): def test_only_django_object_types(self):
class TestType(ObjectType): class Query(ObjectType):
foo = String() something = DjangoListField(String)
with pytest.raises(AssertionError): with pytest.raises(TypeError) as excinfo:
DjangoListField(TestType) Schema(query=Query)
assert (
"Query fields cannot be resolved. DjangoListField only accepts DjangoObjectType types as underlying type"
in str(excinfo.value)
)
def test_only_import_paths(self): def test_only_import_paths(self):
list_field = DjangoListField("graphene_django.tests.schema.Human") list_field = DjangoListField("graphene_django.tests.schema.Human")
@ -262,6 +268,69 @@ class TestDjangoListField:
] ]
} }
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): def test_get_queryset_filter(self):
class Reporter(DjangoObjectType): class Reporter(DjangoObjectType):
class Meta: class Meta: