在 Django 中使用 **dict 作为 create/update_or_create 方法的参数 - 不一致的异常

Using **dict as an argument in Django for create/update_or_create methods - Inconsistent Exceptions

我有一个看起来像这样的字典:

profile_data={'trial_duration': 0, 'tac_agreed': True, 'email': 'blahblah@gmail.com', 'signup_method': 'google', 'social_id': '2343432432', 'social_platform': 'google', 'name': 'blahblah tester'}

我想使用update_or_create方法将这个字典映射到两个不同的模型对象。但是,Django 处理这个问题的方式似乎有些不一致。

我有一个模型 SocialInformation:

class SocialInformation(models.Model):

    social_id = models.CharField(max_length=256, blank=True, null=True)
    social_platform = models.CharField(max_length=256, choices=SOCIAL_PLATFORM_CHOICES, default='', blank=True, null=True)

当我使用以下行时,它无一例外地执行并且值按预期映射,即使 profile_data 字典中的大多数项目都不是SocialInformation 模型上的字段,映射只是忽略不相关的字段并采用相关的字段。

social_info, created = SocialInformation.objects.update_or_create(defaults={**profile_data})

但是,当我对不同的模型执行相同的操作时,配置文件:

class Profile(models.Model):


    owner = models.OneToOneField('auth.User', primary_key=True, on_delete=models.CASCADE)
    name = EncryptedCharField(max_length=200, default='', blank=True, null=True)
    email = models.EmailField(blank=True)
    trial_duration = models.IntegerField(default=7)
    signup_method = models.CharField(max_length=256, choices=SINGUP_METHOD_CHOICES, default='', 
                                     blank=True)

etc. etc.

如果我执行同一行:

profile, created = Profile.objects.update_or_create(owner=user, defaults={**profile_data})

我收到以下错误:

FieldError: Invalid field name(s) for model Profile: 'social_id', 'social_platform'.

为什么它不像 SocialInformation 查询那样忽略不在 Profile 模型中的字段?

不是模型不同,而是一种情况是更新对象,另一种情况是创建对象。

在第一个例子中,它正在更新一个对象,所以非字段are silently ignored

第二个例子是trying to create the object,不允许无效的字段名。

顺便说一句,SocialInformation.objects.update_or_create(defaults={**profile_data}) 我觉得不对劲。您没有过滤以查找要更新的 SocialInformation。看起来您的数据库中可能只有一个 SocialInformation,并且一直在更新那个。如果您手动添加另一个 SocialInformation(例如通过 Django 管理员),那么我希望该行开始抛出 MultipleObjectsReturned 异常。