get_node is not called on related objects
See original GitHub issueCurrently get_node
is not called on related models. i.e.
class Customer(models.Model):
display_name = models.CharField()
....
class Member(models.Model):
customer = models.ForeignKey(Customer)
....
class Customer(DjangoObjectType):
class Meta:
model = models.Customer
filter_fields = []
interfaces = [graphene.Node]
@classmethod
def get_node(cls, info, id):
print('NEVER CALLED')
return None
Then querying with
member(id:"...") {
customer {
id
}
}
Does not result in get_node
being called. this is because get_node
is only called on Relay Nodes. However relay nodes expect an ID
to be passed in via GraphQL. Instead I would like the get_node
to be called with the id for the related object.
If this support was added it means you can add per-object level auth.
Furthermore as get_node
calls get_queryset
, all you would have to do is to filter out all the objects a user isn’t allowed to access i.e.
class Customer(DjangoObjectType):
@classmethod
def get_queryset(cls, queryset, info):
return queryset.filter(admins__in=[info.context.user])
For example lets say Im allowed to see a list of Members, some of those Members are not under the Customer that I am an admin of. However I should still be able to interact with them, as they have some other relationship to my Customer. Maybe the Member is related to another Member under my Customer, and I can access them via that path. However I don’t want to to give an admin the ability to view other Customers. This would achieve that.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:4
- Comments:6 (1 by maintainers)
Top GitHub Comments
The above accomplishes that. Note this will remove any optimisation of select/prefect_related(), as we hit the DB each time. However I don’t believe there is any other performance hit if youre not using selected/prefetch_related, as Django still has to access the DB when following the related model. I still need to verify this though
We could possibly accommodate for the related model already having been loaded by checking
root._state.fields_cache
, however if its preloaded we wouldn’t be able to useget_node
to check if the person is authorised to view it without hitting the DB again anyway.The method used, here is similar to customising the Django RelatedManager for the Model.
Ive made this an Issue instead of PR, as Im still not familiar enough with this library to know of all the gotchas, so figured its best that this is something people opt into. Although I’ll be looking at a way to make this the default behaviour for myself. Maybe subclass
DjangoObjectType
or somethingThis issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.