Extend resolution system for deriving a DjangoObjectType from a django model
See original GitHub issueIs your feature request related to a problem? Please describe.
The assumption of this package is that there is only ever 1 DjangoObjectType subclass for each Django model. A pretty common counterexample is when I have a Profile model with a profile photo on it as well as a phone number, address, and misc other private information.
In public contexts, I would want to show a limited subset of these fields. Perhaps we would define it with
class ProfilePublicNode(DjangoObjectType):
class Meta:
model = Profile
fields = ["username", "profile_photo"]
Meanwhile, there are situations where I would want to show the entire set of fields, such as when allowing a user to update their own profile.
Example:
class ProfilePrivateNode(DjangoObjectType):
class Meta:
model = Profile
fields = list(ProfileNode._meta.fields.keys()) + ["phone_number", "other_secret_stuff"]
This is well and good. WE CAN DO THIS.
Where we have problems is when I have another object where I want to nest a public or private node like this.
Say:
class ArticleNode(DjangoObjectType):
class Meta:
model = Article
fields = ["title", "body_text", "author"]
…where author
is a Profile
model. I have no control over whether ProfilePublicNode
or ProfilePrivateNode
is used. I just get whichever one is defined last in the file.
Currently, graphene-django
populates the registry (https://github.com/graphql-python/graphene-django/blob/main/graphene_django/registry.py) each time a subclass of DjangoObjectType
is defined: https://github.com/graphql-python/graphene-django/blob/main/graphene_django/types.py#L275
The registry is implemented as a dictionary where they key is the django model and the value is the DjangoObjectType
subclass. It only has the ability to store one graphene type per django model. And so the type which is defined last is the type that wins.
This is reenforced by the dead code assertion here which has survived since the initial commit: https://github.com/graphql-python/graphene-django/blob/main/graphene_django/registry.py#L15-L17
This is really not ideal for reasons:
- it makes distinctions like public/private fields implicit, not explicit
- it does not give sufficient control over resolution of nested objects
Describe the solution you’d like
While preserving the existing automatic registry magic for backwards compatibility, I would like to allow the DjangoObjectType subclass to explicitly specify the desired DjangoObjectType subclass for its nested related objects.
Describe alternatives you’ve considered
- Strawberry (just discovered today, looks neat, a little bare bones Flask-esque for my feature-building urgency)
- Crying.
- Moving to Siberia and tending to a flock of Yaks, never to see a computer again
Additional context
N/A
Issue Analytics
- State:
- Created 3 years ago
- Comments:7
Top GitHub Comments
Thanks for your help - will send over a docs PR soon to add a note to this effect.
Well, while this has been equally enlightening and embarrassing, I guess the one thing that could be added now is an opt-in
STRICT_MODE
where all node relations must be explicitly defined for safety so that the auto-registry goes unused. Also, a mechanism to perform resolutions for cyclic graphs based on strings - assuming that’s not already supported.