得到“不存在或是m2m字段”。尝试保存在DRF中时,我的uuid(主键)出现错误 [英] Getting "doesn't exist or is m2m field" error on my uuid (primary key) when trying to save in DRF

查看:129
本文介绍了得到“不存在或是m2m字段”。尝试保存在DRF中时,我的uuid(主键)出现错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经编写了自己的批量 save(),因为我无法获取内部的 save() ListSerializer 的方法来调用相关方法( create()& update()),具体取决于查询有效负载。该模型称为 Product ,其主键为 uuid 。当我使用 updated_fields kwarg调用Product绑定的 save()方法时,我得到:

I've written my own bulk save() because I can't get the internal save() method of ListSerializer to call the relevant method (create() & update()) depending on the query payload. The model is called Product whose primary key is a uuid. When I call Product's bound save() method with the updated_fields kwarg, I get:


ValueError:以下字段在此模型中不存在或为m2m字段:uuid

ValueError: The following fields do not exist in this model or are m2m fields: 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

这是相关的尾巴追溯的一部分:

Here's the relevant tail part of the traceback:


partial_update $ b中的文件 /my/app/views/API/product.py第162行$ b serializer.save()

File "/my/app/views/API/product.py", line 162, in partial_update serializer.save()

文件 /my/app/views/API/serializers.py,第72行,保存
update_fields = [ k对于obj.items()中的k,v

File "/my/app/views/API/serializers.py", line 72, in save update_fields = [k for k,v in obj.items()]

文件 /lib/python3.5/site-packages/d jango / db / models / base.py,第792行,保存
%','.join(non_model_fields))

File "/lib/python3.5/site-packages/django/db/models/base.py", line 792, in save % ', '.join(non_model_fields))

ValueError:以下字段在此模型中不存在,或者是m2m字段:uuid

ValueError: The following fields do not exist in this model or are m2m fields: uuid

以下是 Product的相关部分定义:

class Product(models.Model):
    uuid = models.UUIDField(primary_key=True, default=uuid.uuid4)

因此,它不是m2m,并且该字段确实存在。那么,此错误的原因是什么?

So, it's not a m2m, and that field does exist. What's the cause of this error then?

推荐答案

该错误来自此行,其中Django比较 update_fields 您已经提供了模型字段。

The error comes from this line where Django compares update_fields you've provided with Model 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 的旁边。

Unfortunately the error message is a little misleading because all fields with primary_key=True (like your uuid field) are filtered out, beside m2m ones.

        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 不为空,并且引发异常。

That's the reason why non_model_fields are not empty and exception is raised.

要解决您的问题,您需要摆脱保存前从 obj 中找到uuid 键。

To fix your problem, you need to get rid of uuid key from obj before saving.

        ...
        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()会给出相同的结果。

BTW you don't need this list comprehension to get update_fields - you can use obj.keys() which gives same result.

这篇关于得到“不存在或是m2m字段”。尝试保存在DRF中时,我的uuid(主键)出现错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆