Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
G
graphene-django-optimizer-reloaded
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
AlekSIS®
Libraries
graphene-django-optimizer-reloaded
Commits
055db7d2
Unverified
Commit
055db7d2
authored
5 years ago
by
NyanKiyoshi
Browse files
Options
Downloads
Patches
Plain Diff
Fix variable handling and null values
parent
16894bc3
No related branches found
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
graphene_django_optimizer/query.py
+6
-6
6 additions, 6 deletions
graphene_django_optimizer/query.py
tests/graphql_utils.py
+4
-4
4 additions, 4 deletions
tests/graphql_utils.py
tests/schema.py
+13
-7
13 additions, 7 deletions
tests/schema.py
tests/test_resolver.py
+35
-15
35 additions, 15 deletions
tests/test_resolver.py
with
58 additions
and
32 deletions
graphene_django_optimizer/query.py
+
6
−
6
View file @
055db7d2
...
...
@@ -4,6 +4,8 @@ from django.db.models.fields.reverse_related import ManyToOneRel
from
django.core.exceptions
import
FieldDoesNotExist
from
django.db.models
import
ForeignKey
,
Prefetch
from
django.db.models.constants
import
LOOKUP_SEP
from
graphene
import
InputObjectType
from
graphene.types.generic
import
GenericScalar
from
graphene.types.resolver
import
default_resolver
from
graphene_django
import
DjangoObjectType
from
graphene_django.fields
import
DjangoListField
...
...
@@ -15,7 +17,7 @@ from graphql.language.ast import (
FragmentSpread
,
InlineFragment
,
Variable
,
ObjectValue
)
)
from
graphql.type.definition
import
(
GraphQLInterfaceType
,
GraphQLUnionType
,
...
...
@@ -216,12 +218,10 @@ class QueryOptimizer(object):
if
isinstance
(
value
,
Variable
):
var_name
=
value
.
name
.
value
value
=
info
.
variable_values
.
get
(
var_name
)
if
isinstance
(
value
,
ObjectValue
):
value
=
{
field
.
name
.
value
:
self
.
_get_value
(
info
,
field
.
value
)
for
field
in
value
.
fields
}
if
isinstance
(
value
,
InputObjectType
):
return
value
.
__dict__
else
:
value
=
value
.
value
return
GenericScalar
.
parse_literal
(
value
)
return
value
def
_optimize_field_by_hints
(
self
,
store
,
selection
,
field_def
,
parent_type
):
...
...
This diff is collapsed.
Click to expand it.
tests/graphql_utils.py
+
4
−
4
View file @
055db7d2
...
...
@@ -13,7 +13,7 @@ from graphql.execution.base import (
from
graphql.pyutils.default_ordered_dict
import
DefaultOrderedDict
def
create_execution_context
(
schema
,
request_string
):
def
create_execution_context
(
schema
,
request_string
,
variables
=
None
):
source
=
Source
(
request_string
,
'
GraphQL request
'
)
document_ast
=
parse
(
source
)
return
ExecutionContext
(
...
...
@@ -21,7 +21,7 @@ def create_execution_context(schema, request_string):
document_ast
,
root_value
=
None
,
context_value
=
None
,
variable_values
=
None
,
variable_values
=
variables
,
operation_name
=
None
,
executor
=
None
,
middleware
=
None
,
...
...
@@ -42,8 +42,8 @@ def get_field_asts_from_execution_context(exe_context):
return
field_asts
def
create_resolve_info
(
schema
,
request_string
):
exe_context
=
create_execution_context
(
schema
,
request_string
)
def
create_resolve_info
(
schema
,
request_string
,
variables
=
None
):
exe_context
=
create_execution_context
(
schema
,
request_string
,
variables
)
parent_type
=
get_operation_root_type
(
schema
,
exe_context
.
operation
)
field_asts
=
get_field_asts_from_execution_context
(
exe_context
)
...
...
This diff is collapsed.
Click to expand it.
tests/schema.py
+
13
−
7
View file @
055db7d2
...
...
@@ -17,6 +17,18 @@ from .models import (
)
def
_prefetch_children
(
info
,
filter_input
):
if
filter_input
is
None
:
filter_input
=
{}
gte
=
filter_input
.
get
(
'
value
'
,
{}).
get
(
'
gte
'
,
0
)
return
Prefetch
(
'
children
'
,
queryset
=
gql_optimizer
.
query
(
Item
.
objects
.
filter
(
value__gte
=
int
(
gte
)),
info
),
to_attr
=
'
gql_custom_filtered_children
'
,
)
class
RangeInput
(
graphene
.
InputObjectType
):
gte
=
graphene
.
Field
(
graphene
.
Int
)
...
...
@@ -42,13 +54,7 @@ class ItemInterface(graphene.Interface):
)
children_custom_filtered
=
gql_optimizer
.
field
(
ConnectionField
(
'
tests.schema.ItemConnection
'
,
filter_input
=
ItemFilterInput
()),
prefetch_related
=
lambda
info
,
filter_input
:
Prefetch
(
'
children
'
,
queryset
=
gql_optimizer
.
query
(
Item
.
objects
.
filter
(
value__gte
=
int
(
filter_input
.
get
(
'
value
'
,
{}).
get
(
'
gte
'
,
0
))),
info
),
to_attr
=
'
gql_custom_filtered_children
'
,
),
prefetch_related
=
_prefetch_children
,
)
def
resolve_foo
(
root
,
info
):
...
...
This diff is collapsed.
Click to expand it.
tests/test_resolver.py
+
35
−
15
View file @
055db7d2
...
...
@@ -56,7 +56,6 @@ def test_should_optimize_with_prefetch_related_as_a_string():
assert_query_equality
(
items
,
optimized_items
)
# @pytest.mark.django_db
def
test_should_optimize_with_prefetch_related_as_a_function
():
# parent = Item.objects.create(name='foo')
# Item.objects.create(name='bar', parent=parent)
...
...
@@ -85,28 +84,49 @@ def test_should_optimize_with_prefetch_related_as_a_function():
assert_query_equality
(
items
,
optimized_items
)
def
test_should_optimize_with_prefetch_related_as_a_function_with_object_input
():
info
=
create_resolve_info
(
schema
,
'''
query {
items(name:
"
foo
"
) {
id
foo
childrenCustomFiltered(filterInput: {value: {gte: 11}}) {
id
value
QUERY_CONNECTION_NESTED_INPUT_OBJECT
=
'''
query($filters: ItemFilterInput) {
items(name:
"
foo
"
) {
id
foo
childrenCustomFiltered(filterInput: $filters) {
edges {
node {
id
value
}
}
}
}
'''
)
qs
=
Item
.
objects
.
filter
(
value__gte
=
11
)
items
=
gql_optimizer
.
query
(
qs
,
info
)
optimized_items
=
qs
.
prefetch_related
(
}
'''
@pytest.mark.parametrize
(
"
variables, expected_gte
"
,
[
({
"
filters
"
:
{
'
value
'
:
{
'
gte
'
:
11
}}},
11
),
({},
0
),
])
@pytest.mark.django_db
def
test_should_optimize_with_prefetch_related_as_a_function_with_object_input
(
variables
,
expected_gte
):
"""
This test attempt to provide a nested object as a variable and a null value
as a filter. The objective is to ensure null and nested objects are properly
resolved.
"""
query
=
QUERY_CONNECTION_NESTED_INPUT_OBJECT
info
=
create_resolve_info
(
schema
,
query
,
variables
=
variables
)
optimized_items
=
Item
.
objects
.
prefetch_related
(
Prefetch
(
'
children
'
,
queryset
=
Item
.
objects
.
filter
(
value__gte
=
11
),
queryset
=
Item
.
objects
.
only
(
'
id
'
,
'
value
'
).
filter
(
value__gte
=
expected_gte
),
to_attr
=
'
gql_custom_filtered_children
'
,
),
)
items
=
gql_optimizer
.
query
(
Item
.
objects
,
info
)
assert_query_equality
(
items
,
optimized_items
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment