fix: foreign key nullable and custom resolver (#1446)

* fix: nullable one to one relation

* fix: makefile
This commit is contained in:
Laurent 2023-08-09 17:28:26 +00:00 committed by GitHub
parent 9a773b9d7b
commit db34d2e815
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 8 deletions

View File

@ -10,7 +10,7 @@ dev-setup:
.PHONY: tests ## Run unit tests .PHONY: tests ## Run unit tests
tests: tests:
py.test graphene_django --cov=graphene_django -vv PYTHONPATH=. py.test graphene_django --cov=graphene_django -vv
.PHONY: format ## Format code .PHONY: format ## Format code
format: format:

View File

@ -302,12 +302,15 @@ def convert_onetoone_field_to_djangomodel(field, registry=None):
reversed_field_name = root.__class__._meta.get_field( reversed_field_name = root.__class__._meta.get_field(
field_name field_name
).remote_field.name ).remote_field.name
try:
return _type.get_queryset( return _type.get_queryset(
_type._meta.model.objects.filter( _type._meta.model.objects.filter(
**{reversed_field_name: root.pk} **{reversed_field_name: root.pk}
), ),
info, info,
).get() ).get()
except _type._meta.model.DoesNotExist:
return None
return custom_resolver return custom_resolver

View File

@ -19,7 +19,11 @@ class Pet(models.Model):
class FilmDetails(models.Model): class FilmDetails(models.Model):
location = models.CharField(max_length=30) location = models.CharField(max_length=30)
film = models.OneToOneField( film = models.OneToOneField(
"Film", on_delete=models.CASCADE, related_name="details" "Film",
on_delete=models.CASCADE,
related_name="details",
null=True,
blank=True,
) )

View File

@ -2062,3 +2062,74 @@ def test_should_query_nullable_foreign_key():
assert result.data["person"] == { assert result.data["person"] == {
"pets": [{"name": "Jane's dog"}], "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,
}