Skip to content

Model inheritance in combination with graphene.Union and DjangoOrderedFilterConnection #1299

Closed
@piccarsso

Description

@piccarsso

For a project I need to retrieve a list of videos from a database, which can be of different types. I need the possibility of filtering and pagination. The model uses inheritance (in this case with django_model_utils and InheritanceManager). So I have a BaseLearnVideo and derived from it e.g. MusicLearnVideo, DrawingLearnVideo.

For example, if I have the following models:

    class BaseLearnVideo():
      objects = InheritanceManager()
      title = models.CharField('Title, max_length=200, blank=False)
    
    class MusicLearnVideo(BaseLearnVideo)
      something_special = models.CharField('Something special', max_length=200, blank=False)
    
    class DrawingLearnVideo(BaseLearnVideo)
      cover_image = models.ImageField('Cover image')

I would like to query all learning videos as a list, a mixed list of the types MusicLearnVideo and DrawingLearnVideo. Therefore, graphene.Union would fit.

So in my schema I have:

    class MusicLearnVideoType(DjangoObjectType):
        class Meta:
            model = MusicLearnVideo
            fields = ('id', 'something_special')
            interfaces = (gql.Node,)
    
    class DrawingLearnVideoType(DjangoObjectType):
        class Meta:
            model = DrawingLearnVideo
            fields = ('id', 'cover_image')
            interfaces = (gql.Node,)
    
    class AllLearnVideosUnion(graphene.Union):
        class Meta:
            types = (MusicLearnVideoType, DrawingLearnVideoType)

  class AllLearnVideosConnection(graphene.Connection):
    class Meta:
        node = AllLearnVideosUnion

It works with graphene.Connection:

    all_learn_videos = graphene.ConnectionField(AllLearnVideosConnection)

    def resolve_all_learn_videos(self, info, **kwargs):
        return BaseLearnVideo.objects.all().select_subclasses()

As there can be a lot of different videos, I don't want to query them all, but have a pagination and filters. What I'd like to make is something like:

    all_learn_videos = DjangoFilterConnectionField(AllLearnVideosUnion)

    def resolve_all_learn_videos(self, info, **kwargs):
        return BaseLearnVideo.objects.all().select_subclasses()

The query:

    {
    edges {
      node {
        __typename
        ... on MusicLearnVideoType {
          id
          somethingSpecial
        }
        ... on DrawingLearnVideoType {
          id
         coverImage
        }
      }
    }
  }

I thought of resolving the queryset beforehand, and addressing the filters and pagination in the resolve function of the query, but as there already is the DjangoFilterConnectionField it would be nice to use that :-) I am not sure if this is even possible from a technical point of view, as I have not gone deep into the code of graphene-django.

Thanks a lot in advance for your thoughts on that!

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions