How to get to the list of a ListSerializer

1,322 views
Skip to first unread message

allard....@wearespindle.com

unread,
Nov 10, 2016, 10:07:29 AM11/10/16
to Django REST framework
Hey there,

I am trying to implement some generic nested saving and I've come a long way so far. But I'm struggling with this part. I want to reuse the instances for saving of reverse foreign keys and many to many's etc. but I can't seem to find the list in the ListSerializer. I followed the docs and created a custom ListSerializer which inherits from the normal list serializer, but there is no instance and it's not instantiated with data so I can't access the data, validated_data or is_valid.

My code simplified looks something like this. It's as bare as possible but I hope it get's the point across.

class BookListSerializer(serializers.ListSerializer):
    def save(self, **kwargs):
        # The super breaks because of incomplete instantiating.
        # Also kwargs is empty.
        # There is only one child here and not a list to be found.

        # In (pseudo) code it would look something like this, but there is no instance:
        for book in self.validated_data:
            if book.instance:
                self.child.update(book)
            else:
                self.child.create(book)

        return my_list


class BookSerializer(serializers.ModelSerializer):
    # Some fields.

    class Meta:
        model = Book
        list_serializer_class = BookListSerializer


class WritableNestedSerializer(serializers.ModelSerializer):
    # This is my implementation for nested writes.
   
    def update(self, instance, validated_data):
        # Here I need to do logic for the saving of books.
        # I want to reuse the instances filled in already, like with a foreign key, which get fetched based on the id field in their validated_data.
        # Otherwise I need to do a query for every id in the validated_data of this serializer, whilst it already has been done.
        for field in validated_data:
            if field == relational:  # Simplified if check.
                        data = validated_data.pop(field)
                        instance_list = self.fields[field].save(data)  # This calls the save of my custom list serializer.

        return super(WritableNestedSerializer, self).update(**kwargs)


class AuthorSerializer(WritableNestedSerializer):
    # Example author serializer with a relation to books.
    books = BookSerializer(many=True)

I would expect a ListSerializer to have some kind of list in it with it's children (or values).

It seems the ListSerializer reuses a single child for everything?
Also why isn't the ListSerializer not instantiated with data automatically so you can call the save, validated_data etc.?

But my main question is: how would I get this to work without adding a bunch of queries?

Thanks in advance for any help!

Benjamin SOULAS

unread,
Jul 25, 2018, 4:58:36 AM7/25/18
to Django REST framework
Hello, I am quite interested in your code implementation, did you make it work successfully? If yes, what modifications did you do?

Regards

allard....@wearespindle.com

unread,
Jul 25, 2018, 7:40:47 AM7/25/18
to Django REST framework
Hey Benjamin,

I managed to make most of it work, just not the part this question was about (finding the list inside a listserializer).


Usage:

class RelatedBookSerializer(RelatedSerializerMixin, serializers.ModelSerializer):
    # Some fields.

    class Meta:
        model = Book


class AuthorSerializer(WritableNestedSerializer):
    # Example author serializer with a relation to books.
    books = RelatedBookSerializer(many=True)

    class Meta:
        model = Author


Benjamin SOULAS

unread,
Jul 25, 2018, 8:21:55 AM7/25/18
to Django REST framework
I watched your project, and I am trully sorry i dont understand ...

Finally I try to find a way to POST something like this:

{
    "channel": [{
        "sourceId": 666,
        "usageId": 666,
        "channelId": 666,
        "cabinetId": 666,
        "zoneId": 5
    },
    ...
    ]
    "subject_major": "Arts"
}

But I dont know how to implement it, but I guess I have to override methods in the ListSerializer. And I forgot to say, I use djongo which is a MongoDB ORM, maybe iti is the issue

allard....@wearespindle.com

unread,
Jul 25, 2018, 8:48:59 AM7/25/18
to Django REST framework
Ah yeah, I do heavily rely on the built in Django ORM in this code so using a different ORM will not work unless you rewrite almost everything.

Benjamin SOULAS

unread,
Jul 25, 2018, 9:06:59 AM7/25/18
to Django REST framework
Ow .. okay, so I guess I got a lot of work ... thx mate !
Reply all
Reply to author
Forward
0 new messages