我编写了自己的批量save()
,因为我无法根据查询有效负载调用相关方法(create()
和update()
(的内部save()
方法ListSerializer
。该模型称为Product
其主键为uuid
。当我使用updated_fields
kwarg 调用 Product 的绑定save()
方法时,我得到:
值错误:此模型中不存在以下字段,或者是 m2m 字段:uuid
以下是save()
:
def save(self):
instances = []
result = []
# Note self.validated_data is a list of multiple OrderedDicts representing
# the json of Product fields. Depending on the request, they will either
# have uuids (so we will update these instances), or won't and hence
# require creation.
for obj in self.validated_data:
uuid = obj.get('uuid', None)
if uuid:
instance = get_object_or_404(Product, uuid=uuid)
update_fields = [k for k,v in obj.items()]
for k, v in obj.items():
setattr(instance, k, v)
instance.save(update_fields=update_fields)
result.append(instance)
else:
instances.append(Product(**obj))
Product.objects.bulk_create(instances)
result += instances
return result
以下是回溯的相关尾部:
文件 "/my/app/views/API/product.py",第 162 行,partial_update serializer.save((
文件 "/my/app/views/API/serializers.py",第 72 行,保存中 update_fields = [k for k,v in obj.items((]
文件 "/lib/python3.5/site-packages/django/db/models/base.py",第 792 行,保存中 % ', '.join(non_model_fields((
值错误:此模型中不存在以下字段,或者是 m2m 字段:uuid
以下是Product
定义的相关部分:
class Product(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)
所以,它不是一个m2m,那个领域确实存在。那么这个错误的原因是什么?
错误来自这一行,其中 Django 将你提供的 Model 字段进行比较update_fields
。
if non_model_fields:
raise ValueError("The following fields do not exist in this "
"model or are m2m fields: %s"
% ', '.join(non_model_fields))
不幸的是,错误消息有点误导,因为所有带有primary_key=True
的字段(如您的uuid
字段(都被过滤掉了,除了m2m
字段。
update_fields = frozenset(update_fields)
field_names = set()
for field in self._meta.fields:
if not field.primary_key:
field_names.add(field.name)
...
non_model_fields = update_fields.difference(field_names)
这就是为什么non_model_fields
不为空并引发异常的原因。
要解决您的问题,您需要在保存之前从obj
中删除uuid
密钥。
...
obj.pop('uuid') # only if mutating validated_data doesn't bother you
update_fields = [k for k,v in obj.items()]
for k, v in obj.items():
setattr(instance, k, v)
instance.save(update_fields=update_fields)
result.append(instance)
顺便说一句,您不需要此列表理解来获得update_fields
- 您可以使用obj.keys()
给出相同结果。
由于在 django 中使用错误的字段名称(列名(而发生