Skip to content
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

Automatic object type field for reverse one-to-one model fields cannot resolve when model field has related_query_name and object type has custom get_queryset #1484

Open
MrThearMan opened this issue Dec 9, 2023 · 0 comments
Labels

Comments

@MrThearMan
Copy link

What is the current behavior?

Given the following models:

from django.db import models

class Example(models.Model):
    pass

class Related(models.Model):
    example = models.OneToOneField(
        Example,
        on_delete=models.CASCADE,
        related_name="related",
        # Important!
        related_query_name="related_item",
    )

... and the following ObjectTypes:

import graphene
from graphene_django import DjangoObjectType
from graphene_django.fields import DjangoConnectionField

class ExampleType(DjangoObjectType):
    class Meta:
        model = Example
        fields = [
            "id",
            "related",
        ]
        connection_class = graphene.Connection
        interfaces = (graphene.relay.Node,)

class RelatedType(DjangoObjectType):
    class Meta:
        model = Related
        fields = [
            "id",
            "example",
        ]
        connection_class = graphene.Connection
        interfaces = (graphene.relay.Node,)
        
    # Important!
    @classmethod
    def get_queryset(cls, queryset, info):
        return queryset

... and the following query definitions:

import graphene
from graphene_django.fields import DjangoConnectionField

class Query(graphene.ObjectType):
    examples = DjangoConnectionField(ExampleType)
    related = DjangoConnectionField(RelatedType)

Now, trying to query like this:

query {
  examples {
    edges {
      node {
        id
        related {
          id
        }
      }
    }
  }
}

... will result in an error like this:

[
  {
    "locations": [
      {
        "column": 9,
        "line": 3,
      },
    ],
    "message": "Example has no field named 'related'",
    "path": [
      "examples",
      "edges",
      0,
      "node",
      "related",
    ],
  }
]

What causes the current behavior?

This happens because of two things:

  1. The Related model field example is a OneToOneField, which has defined a related_query_name different from the field's related_name.

  2. The RelatedType ObjectType defined the get_queryset class method.

When graphene_django.converter.convert_onetoone_field_to_djangomodel creates a the ObjectType for the ExampleType field related, it uses the RelatedType ObjectType's queryset for this check: graphene_django.converter.py:283

Since the RelatedType's get_queryset was modified, this check does not early return, thus we use the custom_resolver below that.

When custom_resolver resolves, it tries to fetch reversed_field_name from the class fields (uses django.db.models.options.py:649). Since related is a reverse relation, it does not exist in _forward_fields_map. However, it's not found from fields_map either, since the keys in fields_map use fields' related_query_names instead of related_names.

Therefore, automatic field object type creation fails in this case (reverse one-to-one fields with get_queryset defined).


What is the expected behavior?

I should be able to make the query described above with the given object type configuration.


What is the motivation / use case for changing the behavior?

I should be able to rely on automatic field generaton for reverse one-to-one relations with related_query_name to object types that have defined get_queryset. This reduces boilerplate code, since otherwise I would need to define the field and resolver manually.


Please tell us about your environment:

  • Version: v3.1.5
  • Platform: Windows 11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant