Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Canonical way to do bulk create in django-rest-framework 3.x?

In 2.x we had a serializer which looked like:

class FooSerializer(serializers.ModelSerializer):
    bar = serializers.PrimaryKeyRelatedField()

    class Meta:
        model = Foo

This effectively was able to handle bulk creates (passing a list as the body of a JSON post request). In 3.x, this endpoint is broken. I've tried to implement something similar to the docs on DRF

class FooListSerializer(serializers.ListSerializer):
    def create(self, validated_data):
        foos = [Foo(**item) for item in validated_data]
        return Foo.objects.bulk_create(foos)

class FooSerializer(serializers.ModelSerializer):
    bar = serializers.PrimaryKeyRelatedField(
        queryset=Bar.objects.all()
        )

    class Meta:
        model = Foo
        list_serializer_class = FooListSerializer

And while this works for a single create request, when I attempt to pass a list I get the error:

AttributeError: 'FooListSerializer' object has no attribute 'object'

I've seen some hacks where __init__ is super'd, but it seems with the creation of the ListSerializer class in 3.x there has to be a cleaner way to do this. Thanks in advance.

like image 209
Quentin Donnellan Avatar asked Jan 12 '15 15:01

Quentin Donnellan


People also ask

What is the difference between ModelSerializer and HyperlinkedModelSerializer?

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys. By default the serializer will include a url field instead of a primary key field.

What is renderers in Django REST framework?

The rendering process takes the intermediate representation of template and context, and turns it into the final byte stream that can be served to the client. REST framework includes a number of built in Renderer classes, that allow you to return responses with various media types.

What is Restapi in Django?

REST APIs are an industry-standard way for web services to send and receive data. They use HTTP request methods to facilitate the request-response cycle and typically transfer data using JSON, and more rarely - HTML, XML and other formats.

What does JSONParser do Django?

JSONParser. It parses the incoming request JSON content into python content type dict. It is used if "Content-Type" is set to "application/json".


1 Answers

You don't show how your code is making a FooSerializer instance. The Django REST Framework 3 documentation says:

To serialize a queryset or list of objects instead of a single object instance, you should pass the many=True flag when instantiating the serializer. You can then pass a queryset or list of objects to be serialized.

So, it seems that your code should detect whether the data contains one instance or many, and:

  • serializer = FooSerializer() to handle one instance, or
  • serializer = FooSerializer(many=True) to handle a list of many instances.

Explicit is better than implicit :-)

like image 178
bignose Avatar answered Sep 28 '22 22:09

bignose