场景
我在两种型号之间有一种多对多的关系:
供应商
class Supplier(models.Model):
class Meta:
unique_together = ['supplier_no', 'supplier_name']
ordering = ['supplier_name']
supplier_no = models.IntegerField(blank=False, null=False)
supplier_name = models.CharField(max_length=180)
...
updated = models.DateTimeField(auto_now=True, blank=True)
updated_by = models.ForeignKey(UsaUser, on_delete=models.CASCADE, blank=True, null=True,
related_name='supplierUpdatedByUser')
def __str__(self):
return self.supplier_name
工厂
class Plant(models.Model):
class Meta:
unique_together = ['plant_no', 'plant_name']
ordering = ['plant_no']
plant_no = models.IntegerField(unique=True)
plant_name = models.CharField(max_length=180, unique=True)
...
suppliers = models.ManyToManyField(Supplier, related_name='plants')
updated = models.DateTimeField(auto_now=True, blank=True)
updated_by = models.ForeignKey(UsaUser, on_delete=models.CASCADE, blank=True, null=True,
related_name='plantUpdatedByUser')
def __str__(self):
return self.plant_name
简单地说:一个供应商可以活跃在任何数量的工厂中,一个工厂可以有任何数量的供应商。
这是SupplierSerializer,其创建方法有问题:
class SupplierSerializer(serializers.ModelSerializer):
plants = PlantSerializer(many=True) # serializes entire supplier objects instead of just returning the pk
class Meta:
model = Supplier
fields = ['id', 'supplier_no', 'supplier_name', ... 'plants']
def create(self, validated_data):
# Add the UsaUser as a blameable field, which will be passed in the 'context' object to the serializer.
validated_data.update({"updated_by": self.context['request'].user})
assoc_plants = validated_data.pop('plants') # remove the many-to-many association from the data before saving
supplier = Supplier.objects.create(**validated_data)
# Now add in the associated plants
for plant in assoc_plants:
supplier.plants.add(plant)
return supplier
...
问题:
创建供应商时,我得到以下400响应:
{"plants":[{"non_field_errors":["Invalid data. Expected a dictionary, but got int."]},{"non_field_errors":["Invalid data. Expected a dictionary, but got int."]}]
如果我从序列化程序中删除以下行:
plants = PlantSerializer(many=True)
问题解决了。然而,我希望完整的植物对象返回到我的前端,而不仅仅是植物ID。
我想也许我需要返回完整的Plant对象,因为错误表明它正在查找字典,但后来我又遇到了另一个错误:
{"plants":[{"plant_no":["plant with this plant no already exists."],"plant_name":["plant with this plant name already exists."]}]}
样本请求有效载荷
{"供应商编号":"5052","供应商名称":"我的供应商","is_active":true,"植物":[1,10]}
^^1和10是植物的pk
通过整个工厂对象时:
{quot;supplier_no":"54564","supplier_name":"MySuppeir","is_active":true,"plants":[{quot;id"1,"plant_no":1,"plant_name":"AutoPlant1","is _active"}]}
我认为您希望使用已经创建的植物。然后您可以使用一些额外的字段。
class SupplierSerializer(serializers.ModelSerializer):
plants = PlantSerializer(many=True, read_only = True) # set it as read_only
plant_ids = serializers.ListField(
child = serializers.IntegerField(),
write_only = True
)
class Meta:
model = Supplier
fields = [..., 'plant_ids'] # add plant_ids
def create(self, validated_data):
plant_ids = validated_data.pop('plant_ids')
supplier = Supplier.objects.create(**validated_data)
supplier.plants.set(plant_ids)
return supplier