简体   繁体   中英

Returning array of deleted objects in single GraphQL mutation (graphene-django)

While in the past I used a GraphQL mutation that deletes a single record, I came up with the idea that this is not ideal in the case I want to delete several records at once since it ended up by calling the mutation that delete 1 record several times (in a loop) which results in several API call over the network.

So I decided to instead modify the mutation to accept has an argument a list of objects or IDs (whatever) on which I can loop in the backend. By doing this, it does only 1 call to the API with all the records to delete.

I managed to do it and the only blocking point that I face is the return statement. I couldn't figure out how to write it.

So if I have a model (in my schema) such as:

class UserType(DjangoObjectType):
  class Meta:
    model = User
    fields = (
        'id',
        'username',
        'password',
        'first_name',
        'last_name',
        'is_active',
        'group_ids',
    )

  full_name = graphene.String()
  full_identification = graphene.String()

In the past I used:

class DeleteUser(graphene.Mutation):
  username = graphene.String()

  class Arguments:
    id = graphene.ID()

  def mutate(self, info, **kwargs):
    user = get_object_or_404(User, id=kwargs['id'])
    user.delete()
    return user

class Mutation(graphene.ObjectType):
  delete_user = DeleteUser.Field()

But now I want to do something such as:

class DeleteUsers(graphene.Mutation):
  users = graphene.List(UserType)
  username = graphene.String()

  class Arguments:
    ids = graphene.List(graphene.ID)

  def mutate(self, info, **kwargs):
    deleted_users = []
    for user in User.objects.filter(id__in=kwargs['ids']):
        user.delete()
        deleted_users.append(user)
    return deleted_users

class Mutation(graphene.ObjectType):
  delete_users = DeleteUsers.Field()

You can see in the mutate(..) method of DeleteUsers class that I try to return the deleted_users to be able to do something like: "Users X, Y and Z have been deleted" in the frontend. But I haven't been able to retrieve the data of the users. How can I achieve it? Maybe I'm missing something.

Currently the GraphQL query I tried for that is:

mutation {
    deleteUsers(
        ids: [5,6,7],
    ) {
        users {
            username
    }
  }
}

but it doesn't work, saying users is null ... Don't know how I could retrieve the users in the query.

Thanks in advance.

Well I finally figured out what was the problem (seems talking about a problem solves it, next time I'll try with a plastic duck).

While the deleted_users was a correct list with the Users, the ouput type of my mutation wasn't set.

So the solution is to add:

class Meta:
  output = graphene.List(UserType)

in my mutation

which results in:

class DeleteUsers(graphene.Mutation):

  class Arguments:
    ids = graphene.List(graphene.ID)

  class Meta:
    output = graphene.List(UserType)

  def mutate(self, info, **kwargs):
    deleted_users = []
    for user in User.objects.filter(id__in=kwargs['ids']):
        user.delete()
        deleted_users.append(user)
    return deleted_users

Which can be called with the following:

mutation {
    deleteUsers(
        ids: [5,6,7],
    ) {
    username
    firstName
    # ...
    # And other fields ...
    # ...
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM