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

Set any arbitrary meta fields onto the meta instance #1161

Closed
wants to merge 1 commit into from

Conversation

jkimbo
Copy link
Member

@jkimbo jkimbo commented Mar 15, 2020

Following on from #1007

This PR sets all extra Meta class fields on the _meta instance. Currently any extra fields on the Meta class are lost. This PR keeps them around so that they can be used by application code.

Examples of why this is useful:

  1. If you wanted to create some custom checks that all DjangoObjectTypes are using the fields meta option it's not currently possible. After this PR you could create this function:
def enforce_only_fields(schema):
	types = schema.get_type_map()
	for _, t in types.items():
		if issubclass(t.graphene_type, DjangoObjectType):
			assert t.graphene_type._meta.fields
  1. You could implement field level permissions in Graphene Django by setting a default resolver and defining some kind of auth configuration like this:
    def authed_resolver(attrname, default_value, root, info, **args):
        auth_map = info.parent_type.graphene_type._meta.auth 
        if attrname in auth_map:
            perm_checks = auth_map[attrname]
            checks = [check(root, info) for check in perm_checks]
            if not all(checks):
                return None
        return graphene.types.resolver.default_resolver(
            attrname, default_value, root, info, **args
        )

    def staff_required(obj, info):
		if not info.context.user.is_staff:
			return False
        return True

    class AuthedType(DjangoObjectType):
        email = graphene.String()

        class Meta:
            model = Reporter
            default_resolver = authed_resolver
            auth = {
				"email": [staff_required]
			}

@jkimbo
Copy link
Member Author

jkimbo commented Mar 15, 2020

Discussed with @syrusakbary on Slack and I'm going to close this PR because this can better be solved in specific cases in Graphene Django:

Meta is intentionally “type safe”, I don’t think should be used as a bag for any kind of info.
The same can be achieved by creating another class inside of the Graphene Type

   class AuthedType(DjangoObjectType):
       email = graphene.String()
       class Meta:
           model = Reporter
           default_resolver = authed_resolver
       class MetaAuth:
           email = [staf_required]

@jkimbo jkimbo closed this Mar 15, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant