Krystian K
Krystian K

Reputation: 377

<PYTHON DRF> Why am I getting only one value instead of list from request.data?

I have little problem with accessing to all values from request.data.

Here my code and screens:

My viewset:

class LorebookViewset(ModelViewSet):
    queryset = Lorebook.objects.all()
    serializer_class = LorebookSerializer
    permission_classes = (
        permissions.IsAuthenticated,
    )

    def perform_create(self, serializer):
        data = self.request.data
        print(data)
        print(data['teams'])

Serializer:

class LorebookSerializer(serializers.ModelSerializer):
    teams = serializers.StringRelatedField(many=True, read_only=True)
    categories = serializers.StringRelatedField(many=True, read_only=True)
    author = serializers.StringRelatedField(read_only=True)

    class Meta:
        model = Lorebook
        fields = '__all__'

Model:

class Lorebook(models.Model):
    title = models.CharField(max_length=50, unique=True)
    cover = models.FileField(default='lorebooks/cover.jpg', null=True)
    thumbnail = models.FileField(default='lorebooks/thumb.jpg', null=True)
    banner = models.FileField(default='lorebooks/banner.jpg', null=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    content = models.TextField()
    tags = ArrayField(models.TextField(), default=list)
    categories = models.ManyToManyField(Category)
    teams = models.ManyToManyField(Team)
    date_created = models.DateTimeField(auto_now_add=True)
    trailer = models.TextField()
    is_read = models.BooleanField(default=False)

    def __str__(self):
        return self.title

Data in Postman: Postman data

Print in perform_create in viewset: data on server

Why am I getting only last value from teams instead of list?

Upvotes: 1

Views: 412

Answers (1)

Mike Sandford
Mike Sandford

Reputation: 1365

This is actually what you're supposed to get as per the spec of a QueryDict even if it's not what you as a person who is used to interacting with Python dicts would expect. The spec returns the last value for any key whose value is a list.

https://docs.djangoproject.com/en/3.1/ref/request-response/#django.http.QueryDict.update

I believe the idea here is to prevent code that kind of naively assumes that you're asking for/getting a single item from blowing up when it gets a list of items instead.

If you want to get the whole list:

    def perform_create(self, serializer):
        data = self.request.data
        print(data)
        print(data.getlist('teams')

should do the trick.

Upvotes: 1

Related Questions