Skip to content

Commit

Permalink
fix: foreign key nullable and custom resolver (graphql-python#1446)
Browse files Browse the repository at this point in the history
* fix: nullable one to one relation

* fix: makefile
  • Loading branch information
superlevure committed Aug 10, 2023
1 parent 80294b4 commit 412705c
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ dev-setup:

.PHONY: tests ## Run unit tests
tests:
py.test graphene_django --cov=graphene_django -vv
PYTHONPATH=. py.test graphene_django --cov=graphene_django -vv

.PHONY: format ## Format code
format:
Expand Down
15 changes: 9 additions & 6 deletions graphene_django/converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,12 +302,15 @@ def custom_resolver(root, info, **args):
reversed_field_name = root.__class__._meta.get_field(
field_name
).remote_field.name
return _type.get_queryset(
_type._meta.model.objects.filter(
**{reversed_field_name: root.pk}
),
info,
).get()
try:
return _type.get_queryset(
_type._meta.model.objects.filter(
**{reversed_field_name: root.pk}
),
info,
).get()
except _type._meta.model.DoesNotExist:
return None

return custom_resolver

Expand Down
6 changes: 5 additions & 1 deletion graphene_django/tests/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ class Pet(models.Model):
class FilmDetails(models.Model):
location = models.CharField(max_length=30)
film = models.OneToOneField(
"Film", on_delete=models.CASCADE, related_name="details"
"Film",
on_delete=models.CASCADE,
related_name="details",
null=True,
blank=True,
)


Expand Down
71 changes: 71 additions & 0 deletions graphene_django/tests/test_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -2065,3 +2065,74 @@ def resolve_person(self, info, name):
assert result.data["person"] == {
"pets": [{"name": "Jane's dog"}],
}


def test_should_query_nullable_one_to_one_relation_with_custom_resolver():
class FilmType(DjangoObjectType):
class Meta:
model = Film

@classmethod
def get_queryset(cls, queryset, info):
return queryset

class FilmDetailsType(DjangoObjectType):
class Meta:
model = FilmDetails

@classmethod
def get_queryset(cls, queryset, info):
return queryset

class Query(graphene.ObjectType):
film = graphene.Field(FilmType, genre=graphene.String(required=True))
film_details = graphene.Field(
FilmDetailsType, location=graphene.String(required=True)
)

def resolve_film(self, info, genre):
return Film.objects.filter(genre=genre).first()

def resolve_film_details(self, info, location):
return FilmDetails.objects.filter(location=location).first()

schema = graphene.Schema(query=Query)

Film.objects.create(genre="do")
FilmDetails.objects.create(location="London")

query_film = """
query getFilm($genre: String!) {
film(genre: $genre) {
genre
details {
location
}
}
}
"""

query_film_details = """
query getFilmDetails($location: String!) {
filmDetails(location: $location) {
location
film {
genre
}
}
}
"""

result = schema.execute(query_film, variables={"genre": "do"})
assert not result.errors
assert result.data["film"] == {
"genre": "DO",
"details": None,
}

result = schema.execute(query_film_details, variables={"location": "London"})
assert not result.errors
assert result.data["filmDetails"] == {
"location": "London",
"film": None,
}

0 comments on commit 412705c

Please sign in to comment.