Skip to content

Commit 412705c

Browse files
committed
fix: foreign key nullable and custom resolver (graphql-python#1446)
* fix: nullable one to one relation * fix: makefile
1 parent 80294b4 commit 412705c

File tree

4 files changed

+86
-8
lines changed

4 files changed

+86
-8
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ dev-setup:
1010

1111
.PHONY: tests ## Run unit tests
1212
tests:
13-
py.test graphene_django --cov=graphene_django -vv
13+
PYTHONPATH=. py.test graphene_django --cov=graphene_django -vv
1414

1515
.PHONY: format ## Format code
1616
format:

graphene_django/converter.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -302,12 +302,15 @@ def custom_resolver(root, info, **args):
302302
reversed_field_name = root.__class__._meta.get_field(
303303
field_name
304304
).remote_field.name
305-
return _type.get_queryset(
306-
_type._meta.model.objects.filter(
307-
**{reversed_field_name: root.pk}
308-
),
309-
info,
310-
).get()
305+
try:
306+
return _type.get_queryset(
307+
_type._meta.model.objects.filter(
308+
**{reversed_field_name: root.pk}
309+
),
310+
info,
311+
).get()
312+
except _type._meta.model.DoesNotExist:
313+
return None
311314

312315
return custom_resolver
313316

graphene_django/tests/models.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@ class Pet(models.Model):
1919
class FilmDetails(models.Model):
2020
location = models.CharField(max_length=30)
2121
film = models.OneToOneField(
22-
"Film", on_delete=models.CASCADE, related_name="details"
22+
"Film",
23+
on_delete=models.CASCADE,
24+
related_name="details",
25+
null=True,
26+
blank=True,
2327
)
2428

2529

graphene_django/tests/test_query.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2065,3 +2065,74 @@ def resolve_person(self, info, name):
20652065
assert result.data["person"] == {
20662066
"pets": [{"name": "Jane's dog"}],
20672067
}
2068+
2069+
2070+
def test_should_query_nullable_one_to_one_relation_with_custom_resolver():
2071+
class FilmType(DjangoObjectType):
2072+
class Meta:
2073+
model = Film
2074+
2075+
@classmethod
2076+
def get_queryset(cls, queryset, info):
2077+
return queryset
2078+
2079+
class FilmDetailsType(DjangoObjectType):
2080+
class Meta:
2081+
model = FilmDetails
2082+
2083+
@classmethod
2084+
def get_queryset(cls, queryset, info):
2085+
return queryset
2086+
2087+
class Query(graphene.ObjectType):
2088+
film = graphene.Field(FilmType, genre=graphene.String(required=True))
2089+
film_details = graphene.Field(
2090+
FilmDetailsType, location=graphene.String(required=True)
2091+
)
2092+
2093+
def resolve_film(self, info, genre):
2094+
return Film.objects.filter(genre=genre).first()
2095+
2096+
def resolve_film_details(self, info, location):
2097+
return FilmDetails.objects.filter(location=location).first()
2098+
2099+
schema = graphene.Schema(query=Query)
2100+
2101+
Film.objects.create(genre="do")
2102+
FilmDetails.objects.create(location="London")
2103+
2104+
query_film = """
2105+
query getFilm($genre: String!) {
2106+
film(genre: $genre) {
2107+
genre
2108+
details {
2109+
location
2110+
}
2111+
}
2112+
}
2113+
"""
2114+
2115+
query_film_details = """
2116+
query getFilmDetails($location: String!) {
2117+
filmDetails(location: $location) {
2118+
location
2119+
film {
2120+
genre
2121+
}
2122+
}
2123+
}
2124+
"""
2125+
2126+
result = schema.execute(query_film, variables={"genre": "do"})
2127+
assert not result.errors
2128+
assert result.data["film"] == {
2129+
"genre": "DO",
2130+
"details": None,
2131+
}
2132+
2133+
result = schema.execute(query_film_details, variables={"location": "London"})
2134+
assert not result.errors
2135+
assert result.data["filmDetails"] == {
2136+
"location": "London",
2137+
"film": None,
2138+
}

0 commit comments

Comments
 (0)