예제 #1
0
def convert_local_fields(model, convertable_fields):
    """
    Converts user-specified model fields as if they were nullable.
    Also transforms ID to integer field, since it is (usually) an integer.
    """

    # define how each field shall be converted
    field_conversions = {
        django.db.models.fields.AutoField: django.db.models.IntegerField
    }

    fields = [[name, deepcopy(field)]
              for name, field in get_local_fields(model)]

    for i in range(len(fields)):
        # change a field's type if necessary
        new_field = field_conversions.get(fields[i][1].__class__, None)
        if new_field is not None:
            fields[i][1] = new_field()

        # set all fields as nullable
        fields[i][1].null = True

    # convert the fields
    ret = OrderedDict()

    for name, field in fields:
        if name not in convertable_fields:
            continue
        converted = convert_django_field_with_choices(field,
                                                      get_global_registry())
        ret[name] = converted

    return ret
예제 #2
0
    def __init_subclass_with_meta__(
            cls,
            model=None,
            registry=None,
            skip_registry=False,
            only_fields=(),
            exclude_fields=(),
            include_fields=(),
            filter_fields=None,
            interfaces=(),
            filterset_class=None,
            **options,
    ):
        assert is_valid_django_model(model), (
            'You need to pass a valid Django Model in {}.Meta, received "{}".'
        ).format(cls.__name__, model)

        if not registry:
            registry = get_global_registry()

        assert isinstance(registry, Registry), (
            "The attribute registry in {} needs to be an instance of "
            'Registry, received "{}".').format(cls.__name__, registry)

        if not DJANGO_FILTER_INSTALLED and (filter_fields or filterset_class):
            raise Exception(
                "Can only set filter_fields or filterset_class if Django-Filter is installed"
            )

        django_fields = yank_fields_from_attrs(
            construct_fields(model, registry, only_fields, include_fields,
                             exclude_fields),
            _as=Field,
        )

        _meta = DjangoObjectOptions(cls)
        _meta.model = model
        _meta.registry = registry
        _meta.filter_fields = filter_fields
        _meta.fields = django_fields
        _meta.filterset_class = filterset_class

        super(DjangoObjectType,
              cls).__init_subclass_with_meta__(_meta=_meta,
                                               interfaces=interfaces,
                                               **options)

        if not skip_registry:
            registry.register(cls)
예제 #3
0
    def __init_subclass_with_meta__(
        cls,
        model=None,
        registry=None,
        results_field_name=None,
        pagination=None,
        only_fields=(),
        exclude_fields=(),
        filter_fields=None,
        queryset=None,
        filterset_class=None,
        **options,
    ):

        assert is_valid_django_model(model), (
            'You need to pass a valid Django Model in {}.Meta, received "{}".'
        ).format(cls.__name__, model)

        assert pagination is None, (
            'Pagination should be applied on the ListField enclosing {0} rather than its `{0}.Meta`.'
        ).format(cls.__name__)

        if not DJANGO_FILTER_INSTALLED and filter_fields:
            raise Exception(
                "Can only set filter_fields if Django-Filter is installed")

        assert isinstance(queryset, QuerySet) or queryset is None, (
            "The attribute queryset in {} needs to be an instance of "
            'Django model queryset, received "{}".').format(
                cls.__name__, queryset)

        results_field_name = results_field_name or "results"

        baseType = get_global_registry().get_type_for_model(model)

        if not baseType:
            factory_kwargs = {
                "model": model,
                "only_fields": only_fields,
                "exclude_fields": exclude_fields,
                "filter_fields": filter_fields,
                "filterset_class": filterset_class,
                "pagination": pagination,
                "queryset": queryset,
                "registry": registry,
                "skip_registry": False,
            }
            baseType = factory_type("output", DjangoObjectType,
                                    **factory_kwargs)

        filter_fields = filter_fields or baseType._meta.filter_fields
        """
        if pagination:
            result_container = pagination.get_pagination_field(baseType)
        else:
            global_paginator = graphql_api_settings.DEFAULT_PAGINATION_CLASS
            if global_paginator:
                assert issubclass(global_paginator, BaseDjangoGraphqlPagination), (
                    'You need to pass a valid DjangoGraphqlPagination class in {}.Meta, received "{}".'
                ).format(cls.__name__, global_paginator)

                global_paginator = global_paginator()
                result_container = global_paginator.get_pagination_field(baseType)
            else:
        """
        result_container = CustomDjangoListField(baseType)

        _meta = DjangoObjectOptions(cls)
        _meta.model = model
        _meta.queryset = queryset
        _meta.baseType = baseType
        _meta.results_field_name = results_field_name
        _meta.filter_fields = filter_fields
        _meta.exclude_fields = exclude_fields
        _meta.only_fields = only_fields
        _meta.filterset_class = filterset_class
        _meta.fields = OrderedDict([
            (results_field_name, result_container),
            (
                "count",
                Field(
                    Int,
                    name="totalCount",
                    description="Total count of matches elements",
                ),
            ), (
                "page",
                Field(
                    Int,
                    name="page",
                    description="Page Number",
                ),
            ),
            (
                "pageSize",
                Field(
                    Int,
                    name="pageSize",
                    description="Page Size",
                ),
            )
        ])

        super(DjangoListObjectType,
              cls).__init_subclass_with_meta__(_meta=_meta, **options)
예제 #4
0
"""
Field definitions for graphene_django_optimizedextras
"""
from functools import partial
from graphene.utils.str_converters import to_snake_case
from graphene_django.utils import maybe_queryset, is_valid_django_model
from graphene_django_extras.registry import get_global_registry
from graphene_django_extras.utils import get_extra_filters
from graphene_django_extras.base_types import DjangoListObjectBase
from graphene_django_extras.fields import DjangoFilterPaginateListField, DjangoListObjectField
from graphene_django_extras.paginations.utils import _get_count
from .utils import queryset_factory, get_prefetched_attr

registry = get_global_registry()


class OptimizedDjangoFilterPaginateListField(DjangoFilterPaginateListField):
    """ Adds intelligent optimization to the graphene_django_extra's DjangoFilterPaginateListField """
    def get_queryset(self, root, field_name, field_asts, fragments, **kwargs):
        prefetched = get_prefetched_attr(root, to_snake_case(field_name))
        if prefetched:
            print('Using prefetched', field_name)
            return prefetched

        filter_kwargs = {
            k: v
            for k, v in kwargs.items() if k in self.filtering_args
        }
        qs = queryset_factory(self.type.of_type, field_asts, fragments,
                              **kwargs)
        qs = self.filterset_class(data=filter_kwargs, queryset=qs).qs
    def __init_subclass_with_meta__(
            cls,
            serializer_class=None,
            only_fields=(),
            include_fields=(),
            exclude_fields=(),
            input_field_name=None,
            output_field_name=None,
            description="",
            nested_fields=(),
            **options,
    ):

        if not serializer_class:
            raise Exception(
                "serializer_class is required on all DjangoSerializerMutation")

        model = serializer_class.Meta.model

        description = description or "SerializerMutation for {} model".format(
            model.__name__)

        input_field_name = input_field_name or "new_{}".format(
            model._meta.model_name)
        output_field_name = output_field_name or model._meta.model_name

        input_class = getattr(cls, "Arguments", None)
        if not input_class:
            input_class = getattr(cls, "Input", None)
            if input_class:
                warn_deprecation((
                    "Please use {name}.Arguments instead of {name}.Input."
                    "Input is now only used in ClientMutationID.\nRead more: "
                    "https://github.com/graphql-python/graphene/blob/2.0/UPGRADE-v2.0.md#mutation-input"
                ).format(name=cls.__name__))
        if input_class:
            arguments = props(input_class)
        else:
            arguments = {}

        registry = get_global_registry()

        factory_kwargs = {
            "model": model,
            "only_fields": only_fields,
            "include_fields": include_fields,
            "exclude_fields": exclude_fields,
            "nested_fields": nested_fields,
            "registry": registry,
            "skip_registry": False,
        }

        output_type = registry.get_type_for_model(model)

        if not output_type:
            output_type = factory_type("output", DjangoObjectType,
                                       **factory_kwargs)

        django_fields = OrderedDict({output_field_name: Field(output_type)})

        global_arguments = {}
        for operation in ("create", "delete", "update"):
            global_arguments.update({operation: OrderedDict()})

            if operation != "delete":
                input_type = registry.get_type_for_model(model,
                                                         for_input=operation)

                if not input_type:
                    # factory_kwargs.update({'skip_registry': True})
                    input_type = factory_type("input", DjangoInputObjectType,
                                              operation, **factory_kwargs)

                global_arguments[operation].update(
                    {input_field_name: Argument(input_type, required=True)})
            else:
                global_arguments[operation].update({
                    "id":
                    Argument(
                        ID,
                        required=True,
                        description="Django object unique identification field",
                    )
                })
            global_arguments[operation].update(arguments)

        _meta = SerializerMutationOptions(cls)
        _meta.output = cls
        _meta.arguments = global_arguments
        _meta.fields = django_fields
        _meta.output_type = output_type
        _meta.model = model
        _meta.serializer_class = serializer_class
        _meta.input_field_name = input_field_name
        _meta.output_field_name = output_field_name
        _meta.nested_fields = nested_fields

        super(DjangoSerializerMutation,
              cls).__init_subclass_with_meta__(_meta=_meta,
                                               description=description,
                                               **options)
예제 #6
0
    def __init_subclass_with_meta__(
            cls,
            model=None,
            container=None,
            registry=None,
            skip_registry=False,
            connection=None,
            use_connection=None,
            only_fields=(),
            exclude_fields=(),
            filter_fields=None,
            input_for="create",
            nested_fields=(),
            **options,
    ):
        assert is_valid_django_model(model), (
            'You need to pass a valid Django Model in {}.Meta, received "{}".'
        ).format(cls.__name__, model)

        if not registry:
            registry = get_global_registry()

        assert isinstance(registry, Registry), (
            "The attribute registry in {} needs to be an instance of "
            'Registry, received "{}".').format(cls.__name__, registry)

        assert input_for.lower not in ("create", "delete", "update"), (
            'You need to pass a valid input_for value in {}.Meta, received "{}".'
        ).format(cls.__name__, input_for)

        input_for = input_for.lower()

        if not DJANGO_FILTER_INSTALLED and filter_fields:
            raise Exception(
                "Can only set filter_fields if Django-Filter is installed")

        django_input_fields = yank_fields_from_attrs(
            construct_fields(
                model,
                registry,
                only_fields,
                None,
                exclude_fields,
                input_for,
                nested_fields,
            ),
            _as=InputField,
            sort=False,
        )

        for base in reversed(cls.__mro__):
            django_input_fields.update(
                yank_fields_from_attrs(base.__dict__, _as=InputField))

        if container is None:
            container = type(cls.__name__, (InputObjectTypeContainer, cls), {})

        _meta = DjangoObjectOptions(cls)
        _meta.by_polar = True
        _meta.model = model
        _meta.registry = registry
        _meta.filter_fields = filter_fields
        _meta.fields = django_input_fields
        _meta.input_fields = django_input_fields
        _meta.connection = connection
        _meta.input_for = input_for
        _meta.container = container

        super(InputObjectType, cls).__init_subclass_with_meta__(
            # container=container,
            _meta=_meta,
            **options,
        )

        if not skip_registry:
            registry.register(cls, for_input=input_for)