词典的POST列表以及更新或创建

时间:2019-10-04 10:49:38

标签: python django django-rest-framework

我正在尝试使django-rest-framework接受一系列字典,以便在一个api调用中更新或创建许多对象。

我的模特:

class Order(models.Model):

    internal_id = models.CharField(max_length=500, unique=True)
    external_id = models.CharField(max_length=500, blank=True, null=True, unique=True)
    status = models.CharField(max_length=500, blank=True, null=True)

我的序列化器:

class SimpleOrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        fields = '__all__'

我的观点:

class CreateListMixin():
    def get_serializer(self, *args, **kwargs):
        if isinstance(kwargs.get('data', {}), list):
            kwargs['many'] = True
        return super().get_serializer(*args, **kwargs)





class OrderViewSet(CreateListMixin, viewsets.ModelViewSet):
    queryset = Order.objects.all()
    serializer_class = SimpleOrderSerializer
    lookup_field = 'internal_id'

如果我发布带有新internal_id值的字典列表,则此代码非常有用,但是如果我包含一个已经存在的值,我想更新该对象。 django-rest-framework有可能吗?

1 个答案:

答案 0 :(得分:0)

是的,有可能,但是您必须在序列化程序上提供自己的create方法。我建议您阅读"Customizing multiple create" part of the documentation

  

创建多个对象的默认实现是简单地为列表中的每个项目调用.create()。如果要自定义此行为,则需要自定义.create()传递时使用的ListSerializer类的many=True方法。

因此,您需要创建一个SimpleOrderListSerializer来定义所需的行为,例如:

class SimpleOrderListSerializer(serializers.ListSerializer):
    def create(self, validated_data):
        orders = []
        for item in validated_data:
            # Assuming your "identifying" set of fields is only `internal_id`
            internal_id = item.pop('internal_id')
            order, created = Order.objects.update_or_create(
                internal_id=internal_id,
                defaults=item,
            )
            orders.append(order)
        return orders

然后将此序列化器定义为SimpleOrderSerializer的默认列表序列化器:

class SimpleOrderSerializer(serializers.ModelSerializer):
    class Meta:
        model = Order
        list_serializer_class = SimpleOrderListSerializer
        fields = '__all__'