コード例 #1
0
def convert_lazy_field_to_dynamic(field, registry=None):
    model = field.document_type

    def lazy_resolver(root, *args, **kwargs):
        document = getattr(root, field.name or field.db_name)
        if document:
            _type = registry.get_type_for_model(document.document_type)
            only_fields = _type._meta.only_fields.split(",") if isinstance(
                _type._meta.only_fields, str) else list()
            return document.document_type.objects().no_dereference().only(
                *(list(
                    set((only_fields + [
                        to_snake_case(i)
                        for i in get_query_fields(args[0]).keys()
                    ]))))).get(pk=document.pk)
        return None

    def dynamic_type():
        _type = registry.get_type_for_model(model)

        if not _type:
            return None
        return graphene.Field(
            _type,
            resolver=lazy_resolver,
            description=get_field_description(field, registry),
        )

    return graphene.Dynamic(dynamic_type)
コード例 #2
0
def convert_field_to_dynamic(field, registry=None):
    model = field.document_type

    def dynamic_type():
        _type = registry.get_type_for_model(model)
        if not _type:
            return None
        return graphene.Field(_type, description=get_field_description(field, registry))

    return graphene.Dynamic(dynamic_type)
コード例 #3
0
    def model_type(self, type, **kwargs):
        """
        Returns a DjangoListObjectType if converting for lists, Field otherwise.
        """
        if in_kwargs_and_true(kwargs, "list"):
            return self.type_classes[type.model].get_list_type()

        if in_kwargs_and_true(kwargs, "input") or in_kwargs_and_true(
                kwargs, "input_field"):
            raise ValueError("Cannot convert ModelType as input parameter.")

        return graphene.Dynamic(
            lambda: graphene.Field(self.type_classes[type.model]))
コード例 #4
0
ファイル: util.py プロジェクト: vinyll/graphene-django-cud
def create_dynamic_type(field, type_name, registry, required):
    # Use the Input type node from registry in a dynamic type, and create a union with that
    # and the ID
    def dynamic_type():
        _type = registry.get_converted_field(type_name)

        if not _type:
            raise GraphQLError(f"The type {type_name} does not exist.")

        return _type(
            description=getattr(field, "help_text", ""),
            required=is_required(field, required, True),
        )

    return graphene.Dynamic(dynamic_type)
コード例 #5
0
ファイル: schema.py プロジェクト: annshress/helix-server
class CountryType(DjangoObjectType):
    class Meta:
        model = Country

    last_summary = graphene.Field(SummaryType)
    last_contextual_update = graphene.Field(ContextualUpdateType)
    contacts = DjangoPaginatedListObjectField(
        ContactListType,
        pagination=PageGraphqlPagination(page_size_query_param='pageSize'),
        accessor='contacts')
    operating_contacts = DjangoPaginatedListObjectField(
        ContactListType,
        pagination=PageGraphqlPagination(page_size_query_param='pageSize'),
        accessor='operating_contacts')
    contextual_updates = DjangoPaginatedListObjectField(
        ContextualUpdateListType,
        pagination=PageGraphqlPagination(page_size_query_param='pageSize'),
        accessor='contextual_updates')
    summaries = DjangoPaginatedListObjectField(
        SummaryListType,
        pagination=PageGraphqlPagination(page_size_query_param='pageSize'),
        accessor='summaries')
    crises = graphene.Dynamic(lambda: DjangoPaginatedListObjectField(
        get_type('apps.crisis.schema.CrisisListType'),
        pagination=PageGraphqlPagination(page_size_query_param='pageSize'),
        accessor='crises'))
    entries = graphene.Dynamic(lambda: DjangoPaginatedListObjectField(
        get_type('apps.entry.schema.EntryListType'),
        pagination=PageGraphqlPagination(page_size_query_param='pageSize'),
        accessor='entries'))

    @staticmethod
    def get_queryset(queryset, info):
        # graphene_django/fields.py:57 demands we implement this method
        # so that we can filter based on request, but we do not need
        return queryset
コード例 #6
0
    def queryset_type(self, type, **kwargs):
        """
        Returns a field for listing. If the data shall be fetched from a queryset returned by its property,
        the property name is passed via kwargs.
        """
        if in_kwargs_and_true(kwargs, "input") or in_kwargs_and_true(
                kwargs, "input_field"):
            raise ValueError("Cannot convert QuerySet as input parameter.")

        property_name = kwargs.get("property_name", None)

        return graphene.Dynamic(lambda: DjangoNestableListObjectPermissionsField(
            type.type.convert(
                self, list=True
            ),  # listing type is derived from the type passed as the of_type argument
            property_name=property_name))
コード例 #7
0
def convert_lazy_field_to_dynamic(field, registry=None):
    model = field.document_type

    def lazy_resolver(root, *args, **kwargs):
        if getattr(root, field.name or field.db_name):
            return getattr(root, field.name or field.db_name).fetch()

    def dynamic_type():
        _type = registry.get_type_for_model(model)
        if not _type:
            return None
        return graphene.Field(_type,
                              resolver=lazy_resolver,
                              description=get_field_description(
                                  field, registry))

    return graphene.Dynamic(dynamic_type)
コード例 #8
0
def convert_field_to_dynamic(field, registry=None):
    model = field.document_type

    def reference_resolver(root, *args, **kwargs):
        document = getattr(root, field.name or field.db_name)
        if document:
            _type = registry.get_type_for_model(field.document_type)
            only_fields = _type._meta.only_fields.split(",") if isinstance(
                _type._meta.only_fields, str) else list()
            return field.document_type.objects().no_dereference().only(*((list(
                set(only_fields + [
                    to_snake_case(i) for i in get_query_fields(args[0]).keys()
                ]))))).get(pk=document.id)
        return None

    def cached_reference_resolver(root, *args, **kwargs):
        if field:
            _type = registry.get_type_for_model(field.document_type)
            only_fields = _type._meta.only_fields.split(",") if isinstance(
                _type._meta.only_fields, str) else list()
            return field.document_type.objects().no_dereference().only(*(list(
                set(only_fields + [
                    to_snake_case(i) for i in get_query_fields(args[0]).keys()
                ])))).get(pk=getattr(root, field.name or field.db_name))
        return None

    def dynamic_type():
        _type = registry.get_type_for_model(model)
        if not _type:
            return None
        elif isinstance(field, mongoengine.ReferenceField):
            return graphene.Field(_type,
                                  resolver=reference_resolver,
                                  description=get_field_description(
                                      field, registry))
        elif isinstance(field, mongoengine.CachedReferenceField):
            return graphene.Field(_type,
                                  resolver=cached_reference_resolver,
                                  description=get_field_description(
                                      field, registry))
        return graphene.Field(_type,
                              description=get_field_description(
                                  field, registry))

    return graphene.Dynamic(dynamic_type)
コード例 #9
0
def convert_lazy_field_to_dynamic(field, registry=None):
    model = field.document_type

    def lazy_resolver(root, *args, **kwargs):
        document = getattr(root, field.name or field.db_name)
        if document:
            queried_fields = list()
            _type = registry.get_type_for_model(document.document_type)
            filter_args = list()
            if _type._meta.filter_fields:
                for key, values in _type._meta.filter_fields.items():
                    for each in values:
                        filter_args.append(key + "__" + each)
            for each in get_query_fields(args[0]).keys():
                item = to_snake_case(each)
                if item in document.document_type._fields_ordered + tuple(
                        filter_args):
                    queried_fields.append(item)
            return document.document_type.objects().no_dereference().only(
                *(set((list(_type._meta.required_fields) +
                       queried_fields)))).get(pk=document.pk)
        return None

    def dynamic_type():
        _type = registry.get_type_for_model(model)
        if not _type:
            return None
        field_resolver = None
        required = False
        if field.db_field is not None:
            required = field.required
            resolver_function = getattr(
                registry.get_type_for_model(field.owner_document),
                "resolve_" + field.db_field, None)
            if resolver_function and callable(resolver_function):
                field_resolver = resolver_function
        return graphene.Field(
            _type,
            resolver=field_resolver if field_resolver else lazy_resolver,
            description=get_field_description(field, registry),
            required=required,
        )

    return graphene.Dynamic(dynamic_type)
コード例 #10
0
ファイル: schema.py プロジェクト: jjmurre/GOB-API
def _get_inverse_connections_for_references(inverse_references: dict) -> list:
    inverse_connections = []
    for cat_name, collections in inverse_references.items():
        for col_name, relation_names in collections.items():
            for relation_name in relation_names:
                schema_collection_name = model.get_table_name(
                    cat_name, col_name)
                inverse_connections.append({
                    "src_catalog":
                    cat_name,
                    "src_collection":
                    col_name,
                    "src_relation_name":
                    relation_name,
                    "field_name":
                    f"inv_{relation_name}_{cat_name}_{col_name}",
                    "connection_field":
                    graphene.Dynamic(
                        get_inverse_connection_field(schema_collection_name)),
                })
    return inverse_connections
コード例 #11
0
def convert_many_rel_to_djangomodel(field,
                                    registry=None,
                                    input_flag=None,
                                    nested_field=False):
    """
    An override of the original convert function. Takes into account improved fields with ordering and pagination.
    """

    model = field.related_model

    def dynamic_type():
        if input_flag and not nested_field:
            return DjangoListField(graphene.ID)
        else:
            _type = registry.get_type_for_model(model, for_input=input_flag)

            # get list type of the object if it has one
            if hasattr(_type, "get_list_type"):
                _type = _type.get_list_type()

            if not _type:
                return
            elif input_flag and nested_field:
                return DjangoListField(_type)
            elif _type._meta.filter_fields or _type._meta.filterset_class:
                # return nested relations as a field with pagination
                return DjangoNestableListObjectPermissionsField(
                    _type,
                    required=is_required(field) and input_flag == "create",
                    filterset_class=_type._meta.filterset_class,
                )
            else:
                return DjangoListField(_type,
                                       required=is_required(field)
                                       and input_flag == "create")

    return graphene.Dynamic(dynamic_type)
コード例 #12
0
ファイル: schema.py プロジェクト: jjmurre/GOB-API
def get_graphene_query():
    base_models = {}  # SQLAlchemy model per collection

    # Sort references so that if a refers to b, a will be handled before b
    sorted_refs = _get_sorted_references(model)
    missing_relations = get_fieldnames_for_missing_relations(model)
    root_connection_fields = {}

    for ref in sorted_refs:
        # A reference is a "catalogue:collection" string
        pattern = re.compile('(\w+):(\w+)')
        catalog_name, collection_name = re.findall(pattern, ref)[0]
        collection = model.get_collection(catalog_name, collection_name)

        json_attributes = get_collection_json_attributes(collection)

        # Get all references for the collection
        ref_items = get_collection_references(collection)
        connections = [
        ]  # field name and corresponding FilterConnectionField()
        for key in ref_items.keys():
            cat_name, col_name = re.findall(pattern, ref_items[key]["ref"])[0]

            connections.append({
                "dst_name":
                model.get_table_name(cat_name, col_name),
                "connection_field":
                graphene.Dynamic(
                    get_connection_field(
                        model.get_table_name(cat_name, col_name))),
                "field_name":
                key
            })

        inverse_references = get_inverse_references(catalog_name,
                                                    collection_name)
        inverse_connections = _get_inverse_connections_for_references(
            inverse_references)
        missing_rels = missing_relations.get(catalog_name,
                                             {}).get(collection_name, [])

        model_name = model.get_table_name(catalog_name, collection_name)
        base_model = models[model_name]  # SQLAlchemy model
        object_type_fields = {
            "__repr__": lambda self: f"SQLAlchemyObjectType {model_name}",
            **{
                connection["field_name"]: connection["connection_field"]
                for connection in connections
            },
            **{
                connection["field_name"]: connection["connection_field"]
                for connection in inverse_connections
            },
            **get_json_resolvers(catalog_name, collection_name, json_attributes),
            **get_relation_resolvers(connections),
            **get_inverse_relation_resolvers(inverse_connections),
            **get_missing_relation_resolvers(missing_rels),
            **{rel: graphene.JSONString
               for rel in missing_rels},
        }
        meta = type(
            "Meta", (), {
                "model": base_model,
                "exclude_fields": exclude_fields,
                "interfaces": (graphene.relay.Node, )
            })

        root_connection_class = _create_connection_class(
            f"{model_name}Root", object_type_fields, meta)
        rel_connection_class = _create_connection_class(
            f"{model_name}Rel", {
                FIELD.SOURCE_VALUE:
                graphene.String(
                    description=API_FIELD_DESCRIPTION[FIELD.SOURCE_VALUE]),
                FIELD.SOURCE_INFO:
                GenericScalar(
                    description=API_FIELD_DESCRIPTION[FIELD.SOURCE_INFO]),
                API_FIELD.START_VALIDITY_RELATION:
                DateTime(description=API_FIELD_DESCRIPTION[
                    API_FIELD.START_VALIDITY_RELATION]),
                API_FIELD.END_VALIDITY_RELATION:
                DateTime(description=API_FIELD_DESCRIPTION[
                    API_FIELD.END_VALIDITY_RELATION]),
                **object_type_fields,
            }, meta)

        # 'type' is not allowed as an attribute name, so skip it as a filterable attribute
        collection["attributes"].pop('type', None)
        # Let the FilterConnectionField be filterable on all attributes of the collection
        attributes = {
            attr: graphene_type(value["type"], value["description"])
            for attr, value in collection["attributes"].items()
            if not graphene_type(value["type"]) is None
        }
        root_connection_fields[f'{model_name}'] = FilterConnectionField(
            root_connection_class, **attributes)
        connection_fields[f'{model_name}'] = FilterConnectionField(
            rel_connection_class, **attributes)

        # Use root_connection_class for inverse relations as well. No need for bronwaardes here.
        inverse_connection_fields[f'{model_name}'] = FilterConnectionField(
            root_connection_class, **attributes)
        base_models[f'{model_name}'] = base_model

    Query = type(
        "Query",
        (graphene.ObjectType, ),
        # <collection> = FilterConnectionField(<collection>Connection, filters...)
        root_connection_fields)
    return Query
コード例 #13
0
def convert_model_to_input_type(model,
                                input_flag="create",
                                registry=None,
                                exclude=None,
                                only=None):

    djangoType = registry.get_type_for_model(model)
    for_queryset = "order_by" in input_flag or "where" in input_flag
    if "create" in input_flag or "update" in input_flag:
        model_fields = get_model_fields(
            model,
            only_fields=djangoType._meta.input_only_fields,
            exclude_fields=djangoType._meta.input_exclude_fields,
        )
    else:
        model_fields = get_model_fields(
            model,
            only_fields=djangoType._meta.only_fields,
            exclude_fields=djangoType._meta.exclude_fields,
            for_queryset=for_queryset,
        )

    if "where" in input_flag:
        if (djangoType._meta.where_only_fields != "__all__"
                or len(djangoType._meta.where_exclude_fields) > 0):
            assert not (
                djangoType._meta.where_only_fields != "__all__"
                and len(djangoType._meta.where_exclude_fields) > 0
            ), "Only one of where_only_fields or where_exclude_fields parameter can be declared"
            if djangoType._meta.where_only_fields != "__all__":
                exclude_fields = [
                    name for name, field in model_fields
                    if name not in djangoType._meta.where_only_fields
                ]
            else:
                exclude_fields = [
                    name for name, field in model_fields
                    if name in djangoType._meta.where_exclude_fields
                ]
            assert (not "id" in exclude_fields
                    ), "the id field is required for whereInputType"
            model_fields = [(name, field) for name, field in model_fields
                            if name not in exclude_fields]
    elif "order_by" in input_flag:
        if (djangoType._meta.order_by_only_fields != "__all__"
                or len(djangoType._meta.order_by_exclude_fields) > 0):
            assert not (
                djangoType._meta.order_by_only_fields != "__all__"
                and len(djangoType._meta.order_by_exclude_fields) > 0
            ), "Only one of order_by_only_fields or order_by_exclude_fields parameter can be declared"
            if djangoType._meta.order_by_only_fields != "__all__":
                exclude_fields = [
                    name for name, field in model_fields
                    if name not in djangoType._meta.order_by_only_fields
                ]
            else:
                exclude_fields = [
                    name for name, field in model_fields
                    if name in djangoType._meta.order_by_exclude_fields
                ]
            model_fields = [(name, field) for name, field in model_fields
                            if name not in exclude_fields]

    without = ""
    if exclude is not None or only is not None:
        assert not (exclude is not None and only is not None
                    ), "Only one of only or exclude parameter can be declared"
        if only is not None:
            exclude_fields = [
                name for name, field in model_fields if name not in only
            ]
        elif exclude is not None:
            exclude_fields = [
                name for name, field in model_fields if name in exclude
            ]
        model_fields = [(name, field) for name, field in model_fields
                        if name not in exclude_fields]
        exclude_fields.sort()
        without = "without_" + "_".join(exclude_fields) + "_"

    input_type_name = "{}_{}_{}input".format(model.__name__, input_flag,
                                             without)
    input_type_name = to_camel_case(input_type_name)
    input_type = registry.get_type_for_input(input_type_name)
    if input_type:
        return input_type

    def embeded_list_fields():
        return graphene.List(
            convert_model_to_input_type(model,
                                        input_flag="where",
                                        registry=registry))

    def embeded_field():
        return graphene.Field(
            convert_model_to_input_type(model,
                                        input_flag="where",
                                        registry=registry))

    items = OrderedDict()

    if input_flag == "create_nested_many":
        items["create"] = graphene.List(
            convert_model_to_input_type(model,
                                        input_flag="create",
                                        registry=registry))
        items["connect"] = graphene.List(
            convert_model_to_input_type(model,
                                        input_flag="where",
                                        registry=registry))

    elif input_flag == "update_nested_many":
        items["create"] = graphene.List(
            convert_model_to_input_type(model,
                                        input_flag="create",
                                        registry=registry))
        items["delete"] = graphene.List(
            convert_model_to_input_type(model,
                                        input_flag="where",
                                        registry=registry))
        items["connect"] = graphene.List(
            convert_model_to_input_type(model,
                                        input_flag="where",
                                        registry=registry))
        items["disconnect"] = graphene.List(
            convert_model_to_input_type(model,
                                        input_flag="where",
                                        registry=registry))

    elif input_flag == "create_nested":
        items["create"] = graphene.Field(
            convert_model_to_input_type(model,
                                        input_flag="create",
                                        registry=registry))
        items["connect"] = graphene.Field(
            convert_model_to_input_type(model,
                                        input_flag="where",
                                        registry=registry))

    elif input_flag == "update_nested":
        items["create"] = graphene.Field(
            convert_model_to_input_type(model,
                                        input_flag="create",
                                        registry=registry))
        items["delete"] = Boolean()
        items["connect"] = graphene.Field(
            convert_model_to_input_type(model,
                                        input_flag="where",
                                        registry=registry))
        items["disconnect"] = Boolean()

    else:
        if input_flag == "where":
            items["id"] = IdFilter()
        for name, field in model_fields:
            if name == "id" and input_flag in ["create", "update", "where"]:
                continue

            converted = convert_django_field_with_choices(
                field, input_flag=input_flag, registry=registry)
            items[name] = converted
        if "create" in input_flag or "update" in input_flag:
            for name, field in djangoType._meta.input_extend_fields:
                items[name] = field
        if input_flag == "where":
            items["OR"] = graphene.Dynamic(embeded_list_fields)
            items["AND"] = graphene.Dynamic(embeded_list_fields)
            items["NOT"] = graphene.Dynamic(embeded_field)

    ret_type = type(
        input_type_name,
        (graphene.InputObjectType, ),
        items,
    )

    registry.register_input(input_type_name, ret_type)
    return ret_type
コード例 #14
0
 def get_related_model_type(cls, field: models.Field) -> graphene.Dynamic:
     model = field.related_model
     return graphene.Dynamic(cls.get_field_resolver(model, many=type(field) not in cls.foreign_fields))
コード例 #15
0
ファイル: core.py プロジェクト: project-renard-survey/dbas
class StatementGraph(SQLAlchemyObjectType):
    class Meta:
        model = Statement

    text = graphene.String()
    textversions = graphene.Field(TextVersionGraph)
    supports = ArgumentGraph.plural()
    rebuts = ArgumentGraph.plural()
    undercuts = ArgumentGraph.plural()

    def resolve_textversions(self, info, **kwargs):
        return resolve_field_query({
            **kwargs, "statement_uid": self.uid
        }, info, TextVersionGraph)

    def resolve_text(self: Statement, info):
        return self.get_text()

    def resolve_supports(self, info, **kwargs):
        return resolve_list_query(
            {
                **kwargs, "is_supportive": True,
                "conclusion_uid": self.uid
            }, info, ArgumentGraph)

    def resolve_rebuts(self, info, **kwargs):
        return resolve_list_query(
            {
                **kwargs, "is_supportive": False,
                "conclusion_uid": self.uid
            }, info, ArgumentGraph)

    def resolve_undercuts(self, info, **kwargs):
        # Query for all arguments attacking / supporting this statement
        sq = DBDiscussionSession.query(Argument.uid) \
            .filter(Argument.conclusion_uid == self.uid,
                    Argument.is_disabled == False) \
            .subquery()

        # Query for all arguments, which are attacking the arguments from the query above.
        return ArgumentGraph.get_query(info) \
            .filter_by(**kwargs) \
            .filter(
            Argument.is_disabled == False,
            Argument.argument_uid.in_(sq)
        )

    @staticmethod
    def singular():
        return graphene.Field(StatementGraph,
                              uid=graphene.Int(),
                              is_position=graphene.Boolean(),
                              is_disabled=graphene.Boolean())

    @staticmethod
    def plural():
        return graphene.List(StatementGraph,
                             is_position=graphene.Boolean(),
                             is_disabled=graphene.Boolean())

    flat_statements_below = graphene.Dynamic(lambda: graphene.NonNull(
        StatementGraph.plural(),
        description=
        "Returns all texts from the statements in the tree below this statement"
    ))

    def resolve_flat_statements_below(self: Statement, _info):
        return self.flat_statements_below()