Skip to content

DjangoConnectionField triggers django orm sql asserts with complex resolve + filtering #289

Closed
@danyx23

Description

@danyx23

When a DjangoConnectionField is resolved using a custom method that does nontrivial filtering that involve an inner join and a .distinct() call, then resolving this field with a filter fails. This is because the assert in django/db/models/sql/query.py is triggered when DjangoConnectionField.DjangoConnectionField combines the filtered Queryset with an intersection on the queryset from the custom resolve method.

To give a concrete example, in the following model, the given query fails with an exception:

# Models
class FilmDetails(models.Model):
    location = models.CharField(max_length=30)
    film = models.OneToOneField('Film', related_name='details')


class Film(models.Model):
    genre = models.CharField(max_length=2, help_text='Genre', choices=[
        ('do', 'Documentary'),
        ('ot', 'Other')
    ], default='ot')
    reporters = models.ManyToManyField('Reporter',
                                       related_name='films')

# Graphene-Django classes
class FilmType(DjangoObjectType):
        class Meta:
            model = Film
            interfaces = (Node, )
            filter_fields = ('genre',)

class Query(graphene.ObjectType):
    films = DjangoConnectionField(FilmType)

    def resolve_films(self, args, context, info):
         return Film.objects \
              .filter(
                    Q(details__location__contains="Berlin") | 
                    Q(genre__in=['ot']))
              .distinct()

# Test query
f = Film.objects.create()
fd = FilmDetails.objects.create(
    location="Berlin",
    film=f
)

schema = graphene.Schema(query=Query)
query = '''
        query NodeFilteringQuery {
            films {
                edges {
                    node {
                        genre
                    }
                }
            }
        }
 '''

This was discovered with graphene-django 1.3 on python 3.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions