简体   繁体   中英

Getting django.db.utils.OperationalError: sub-select returns 11 columns - expected 1 when trying to add an object to a m2m field

I am new to django rest framework, and I am trying to build api for a todo app using which i can add collaborator to a todo my todo model is as follows:

class Todo(models.Model):
creator = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=255)
collaborators = models.ManyToManyField(User,related_name='collaborators')
def __str__(self):
    return self.title

Serializer.py

class TodoCreateSerializer(serializers.ModelSerializer):
def save(self, **kwargs):
    data = self.validated_data
    user = self.context['request'].user
    title = data['title']
    todo = Todo.objects.create(creator=user, title=title)
    return todo

    class Meta:
    model = Todo
    fields = ('id', 'title',)


class UserObjectSerializer(serializers.ModelSerializer):

    class Meta:
    model = User
    fields = ['username']

class TodoSerializer(serializers.ModelSerializer):
    collaborators = UserObjectSerializer(many=True, required = False)
    class Meta:
        model = Todo
        fields = ['id', 'title', 'collaborators']

class CollaboratorSerializer(serializers.ModelSerializer):
    collaborators = UserObjectSerializer(many=True)
    class Meta:
        model = Todo
        fields = ['collaborators']

and when i try to add collaborator object to my collaborator field using the following method in the viewset

class CollaboratorViewSet(viewsets.ModelViewSet):
serializer_class = CollaboratorSerializer
queryset=Todo.objects.all()
@action(methods=['put'], detail=True, permission_classes=[permissions.IsAuthenticated, ], url_path='add-collaborator', url_name='add_collaborator')
def add_collaborator(self, request, pk=None):
    try:
        todo = Todo.objects.get(pk=pk)
    except Exception:
        return Response({'Error':'Invalid Id'})
    else:
        if request.user == todo.creator:
            try:
                collborators = request.data["collaborators"]
            except KeyError:
                return Response({'Error':'Collaborator field not specified in request'}, status = status.HTTP_400_BAD_REQUEST)
            else:
                collab_list = []
                for collab in collborators:
                    try:
                        collab_name = collab['username']
                    except KeyError:
                        return Response({'Error':'No username provided'}, status = status.HTTP_400_BAD_REQUEST)
                    else:
                        new_collab = User.objects.filter(username=collab_name)
                        if new_collab:
                            collab_list.append(new_collab)
                        else:
                            return Response({'detail':'No user with provided username exists'}, status = status.HTTP_400_BAD_REQUEST)
                todo.collaborators.add(*collab_list)
                return Response({'Success':'Added collaborators successfully'}, status=status.HTTP_200_OK)
        else:
            raise PermissionDenied("You are not the creator of this Todo.")
@action(methods=['patch'], detail=True, permission_classes=[permissions.IsAuthenticated, ], url_path='delete-collaborator', url_name='delete_collaborator')

I get an error django.db.utils.OperationalError: sub-select returns 11 columns - expected 1 but when i use todo.collaborators.set(collaborator_object) collaborator gets added but this way i am able to add only one collaborator and no effect occurs when i try to add multiple collaborators. I know that we can add multiple object to m2m relation fields using.add() method but that's not working when i try to add even one object, i also went through the documentation for.add() method but could not find any help.

Sorry for such a long question and thanks for helping in advance!

I managed to solve the error, actually I was was trying to access the collaborators as

new_collab = User.objects.filter(username=collab_name)

which will return a queryset even if there is a unique user with given username and then i was trying to add collaborator directly to collaborators field which caused this error as it expected an User instance but I was providing a queryset to avoid that I just replaced the above line as

new_collab = User.objects.get(username=collab_name)

which will return a User object instance if it exists so no error is raised and I am able to add multiple as well as single collaborators.

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