【问题标题】:How to serialize ManyToManyField如何序列化多对多字段
【发布时间】:2022-01-16 15:56:26
【问题描述】:

我想序列化 ManyToManyField,但同时,我正在寻找使用 ModelViewSet 更新相同内容的东西。我可以序列化它,但是当我更新它时,我不能。我知道我可以为此制作一个单独的 API,但由于某些要求,我需要坚持一个端点。这是我的代码

class ComponentSerializers(serializers.ModelSerializer):
    class Meta:
        model = coreModel.Component
        fields = '__all__'

class MonitorSerializers(serializers.ModelSerializer):
    device = ComponentSerializers(read_only=True, many=True) 
    class Meta:
        model = models.Monitor
        fields = '__all__'
        read_only_fields = ('id', 'created_at', 'updated_at',)

views.py 是

class MonitorViewSet(viewsets.ModelViewSet):
    authentication_classes = (authentication.TokenAuthentication,)
    permission_classes = (permissions.IsAuthenticated,)
    queryset = models.Monitor.objects.all()
    filter_backends = (DjangoFilterBackend,OrderingFilter,SearchFilter)
    filter_class = superFilter.MonitorFilters
    serializer_class = serializers.MonitorSerializers

【问题讨论】:

  • “我无法更新它”是什么意思?
  • 我要更新device PATCH 请求
  • read_only=设备属性有True标志
  • 当我删除它时,我得到一个错误,因为需要 Dict
  • { "device": [ { "non_field_errors": [ "Invalid data. Expected a dictionary, but got int." ] }, { "non_field_errors": [ "Invalid data. Expected a dictionary, but got int." ] } ] }

标签: python django django-rest-framework


【解决方案1】:

如果你想更新ManytoMany or Related objects

覆盖

def update(self, validated_data):

在 MonitorSerializers 中

class MonitorSerializers(serializers.ModelSerializer):
    device = ComponentSerializers(read_only=True, many=True)
    device_ids = serializers.ListField(write_only=True,
         child = serializers.IntegerField(min_value = 1))
     ....


def update(self, instance, validated_data):
    # Remove component data and save in variable
    iscomponentdataexists = 'device_ids' in validated_data
    if iscomponentdataexists :
        componentdata= validated_data.pop('device_ids')
    instance = super().update(instance, validated_data)  # Update Monitor Data
    # looping through new device_ids list
    if iscomponentdataexists :
        for deviceid in componentdata:
            try:
                obj = coreModel.Component.objects.get(id=deviceid)
                instance.devices.add(obj)
            except coreModel.Component.DoesNotExist:
                pass
        instance.save()
        
    return instance

从设备中删除 read_only=True

【讨论】:

  • 我仍然遇到同样的错误。
  • 是的,我已经完成了..
  • 您遇到了哪个错误?发布用于补丁请求的 json 有效负载
  • { "device": [1,2] }
  • 那么您需要使用现有的序列化程序更改您的序列化程序,您需要提供组件的数据而不是 ids {"device":[{...},{....}]}
猜你喜欢
  • 2018-09-21
  • 1970-01-01
  • 2015-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-14
  • 1970-01-01
相关资源
最近更新 更多