8245 monkey-patch graphene-django to support filtering at all levels

This commit is contained in:
Arthur 2022-10-11 11:36:18 -07:00
parent ffce5d968d
commit d916920978
2 changed files with 49 additions and 8 deletions

View File

@ -1,9 +1,13 @@
import graphene
from graphene_django.converter import convert_django_field
from dcim.fields import MACAddressField, WWNField
from django.db import models
from graphene import Dynamic
from graphene_django.converter import convert_django_field, get_django_field_description
from graphene_django.fields import DjangoConnectionField
from ipam.fields import IPAddressField, IPNetworkField
from taggit.managers import TaggableManager
from dcim.fields import MACAddressField, WWNField
from ipam.fields import IPAddressField, IPNetworkField
from .fields import ObjectListField
@convert_django_field.register(TaggableManager)
@ -21,3 +25,45 @@ def convert_field_to_tags_list(field, registry=None):
def convert_field_to_string(field, registry=None):
# TODO: Update to use get_django_field_description under django_graphene v3.0
return graphene.String(description=field.help_text, required=not field.null)
@convert_django_field.register(models.ManyToManyField)
@convert_django_field.register(models.ManyToManyRel)
@convert_django_field.register(models.ManyToOneRel)
def convert_field_to_list_or_connection(field, registry=None):
"""
From graphene_django.converter.py we need to monkey-patch this to return
our ObjectListField with filtering support instead of DjangoListField
"""
model = field.related_model
def dynamic_type():
_type = registry.get_type_for_model(model)
if not _type:
return
if isinstance(field, models.ManyToManyField):
description = get_django_field_description(field)
else:
description = get_django_field_description(field.field)
# If there is a connection, we should transform the field
# into a DjangoConnectionField
if _type._meta.connection:
# Use a DjangoFilterConnectionField if there are
# defined filter_fields or a filterset_class in the
# DjangoObjectType Meta
if _type._meta.filter_fields or _type._meta.filterset_class:
from .filter.fields import DjangoFilterConnectionField
return DjangoFilterConnectionField(_type, required=True, description=description)
return DjangoConnectionField(_type, required=True, description=description)
return ObjectListField(
_type,
required=True, # A Set is always returned, never None.
description=description,
)
return Dynamic(dynamic_type)

View File

@ -18,11 +18,6 @@ from sentry_sdk.integrations.django import DjangoIntegration
from netbox.config import PARAMS
# Monkey patch to fix Django 4.0 support for graphene-django (see
# https://github.com/graphql-python/graphene-django/issues/1284)
# TODO: Remove this when graphene-django 2.16 becomes available
django.utils.encoding.force_text = force_str # type: ignore
#
# Environment setup