Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
527 views
in Technique[技术] by (71.8m points)

django - How to create multiple instances in DRF?

I have a list of data coming in a request, and after filtering taken out data that needs creation, I'm passing it to the serializer create method, but I'm getting this error:

AssertionError: The `.create()` method does not support writable nested fields by default.
Write an explicit `.create()` method for serializer `apps.some_app.serializers.SomeSerializer`, or set `read_only=True` on nested serializer fields.

My view looks like this:

class MyViewSet(ModelViewSet):
    # Other functions in ModelViewset

    @action(methods=['post'], url_path='publish', url_name='publish', detail=False)
    def publish_data(self, request, *args, **kwargs):
        new_data = util_to_filter_data(request.data)
        serializer = self.serializer_class(data=new_data, many=True)
        if serializer.is_valid(raise_exception=True):
            serializer.create(serializer.validated_data)
            return Response()

I understood the error, that I am passing nested fileds in the create method. But, when I am directly calling my Viewset with single POST request, it is created successfully, even though it too contains nested fields.

What am I doing wrong here?

Here's my serializer:

class SomeSerializer(ModelSerializer):
    # fields
    def create(self, validated_data):
        print("in create")
        return super().create(validated_data)
    
    def save(self, **kwargs):
        print("in save")
        my_nested_field = self.validated_data.pop('my_nested_field', '')
        # Do some operations on this field, and other nested fields
        obj = None
        with transaction.atomic():
            obj = super().save(kwargs)
            # Save nested fields
        return obj

Here in create is being seen in terminal, but not in save.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

you should not use serializer create method directly; instead use save. Also no need to check serializer.is_valid with if when raise_exception=True, if it is not valid it will return the exception

Try following.

class MyViewSet(ModelViewSet):
    # Other functions in ModelViewset

    @action(methods=['post'], url_path='publish', url_name='publish', detail=False)
    def publish_data(self, request, *args, **kwargs):
        new_data = util_to_filter_data(request.data)
        serializer = self.serializer_class(data=new_data, many=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...