我使用来自多个对象的数据获得JSON响应,通过序列化程序运行所有内容并调用serializer.save()
来创建新对象但不更新现有对象。
视图
data = JSONParser().parse(request)
serializer = CellCESaveSerializer(data=data, many = True, context = {'descriptoridlist' : descriptoridlist}, partial=True)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, safe=False)
序列化程序
class StringArrayField(ListField):
"""
String representation of an array field.
"""
def to_representation(self, obj):
obj = super().to_representation(obj)
# convert list to string
return ",".join([str(element) for element in obj])
def to_internal_value(self, data):
data = data.rstrip(",") # Needed because of JSON response
data = data.split(",") # Split string to list
data = [int(i) for i in data] # convert str to int
did = self.context['descriptoridlist']
x = (did,data) # Create Array
return super().to_internal_value(x)
class CellCESaveSerializer(serializers.ModelSerializer):
row = serializers.SlugRelatedField(slug_field="name",queryset=Descriptor.objects.all() ) # foreignkey mit namen
val = StringArrayField()
class Meta:
model = CellCE
fields = ('row','val')
如何在不创建新对象的情况下更新现有对象?
编辑1:
添加@neverwalkaloner更改后,我意识到我需要使用ListSerializer来更新多个对象。我在DRF documentation的帮助下调整了我的代码。 (我将序列化程序更改为ListSerializer,添加了id字段和更新方法。)
串行器:
class CellCESaveSerializer(serializers.ListSerializer):
row = serializers.SlugRelatedField(slug_field="name",queryset=Descriptor.objects.all()) # foreignkey mit namen
val = StringArrayField()
id = serializers.IntegerField()
class Meta:
model = CellCE
fields = ('row','val')
def update(self, instance, validated_data):
CellCE_mapping = {CellCE.id: CellCE for CellCE in instance}
data_mapping = {item['id']: item for item in validated_data}
# Perform creations and updates.
ret = []
for CellCE_id, data in data_mapping.items():
CellCE = CellCE_mapping.get(CellCE_id, None)
if CellCE is None:
ret.append(self.child.create(data))
else:
ret.append(self.child.update(CellCE, data))
# Perform deletions.
for CellCE_id, CellCE in CellCE_mapping.items():
if CellCE_id not in data_mapping:
CellCE.delete()
return ret
我收到错误:
AssertionError: `child` is a required argument.
我缺少什么?
答案 0 :(得分:0)
序列化程序的save()
方法检查序列化程序的self.instance
是否为空。如果self.instance
为空save()
,则会调用create()
方法,否则会调用update()
方法。
因此要使用序列化程序更新实例,您需要传递它的第一个参数更新对象:
obj = CellCE.objects.get(id='some_id') # Object wich will be updated
serializer = CellCESaveSerializer(obj, data=data, many = True, context = {'descriptoridlist' : descriptoridlist}, partial=True)
if serializer.is_valid():
serializer.save()
return JsonResponse(serializer.data, safe=False)
答案 1 :(得分:0)
不需要使用ListSerializer,因为当你传递“many = True”时,它也使用ListSerializer类。如果要更新一次对象,请包含“id”字段并在输入数据中传递其值。