I am using Django as back-end with graphene-django serving the front-end. I am new to both django and graphene so I am not sure what is the best approach to achieve field-level permissions with no code repetition in this set-up. For example, if my model is:
class MyModel(models.Model):
field1 = models.CharField()
field2 = models.CharField()
I want to be able to specify that user1 can read field1 but not field2; when the user1 queries GraphQL for all MyModels it would be only allow to retrieve field1 from rows (nodes) and not field2.
I did a bit of research and found 2 possible alternative solutions but I fear they may not be in the spirit of Django framework and/or conflicting with each other and there may be a better way to achieve this in Django. Ultimately I don't want to be repeating the permissions code in multiple parts of the Django and Graphene back-end so want this to be centralised at the lowest possible level, ideally at the Django model. I need to be able to control full CRUD per field depending on user_id and maybe even have some additional logic. The options I found were:
overriding get_node resolver in graphene-django DjangoObjectType to check for permissions there. Personally I see this as a very bad and last-resort solution as the checks are done only on graphql query/mutation layer and not elsewhere in Django. I could easily write a Django form or view that would not benefit from the permission check unless this is coded again in that form/view.
I could extend the Django model to perform arbitrary per-field checks and this seems the right level where to enforce permission checks but ideally I would prefer to use built-in features or a 'popular' library for this type of stuff. I tried searching for a library but I couldn't find anything that is even remotely production ready or gaining any traction - which leads me to the consider that there may be a better approach to address this problem. Django-field-permissions package seemed on the right path though.
I was wondering if anyone has a view on the best approach to solving this problem that fits Django and Graphene frameworks and without repeating the permissions code everywhere?