gpt4 book ai didi

python - 使用自然键排除 Django 转储数据中的主键

转载 作者:太空狗 更新时间:2023-10-29 21:20:16 31 4
gpt4 key购买 nike

当启用自然键时,如何从 Django 的转储数据生成的 JSON 中排除主键?

我构建了一个我想“导出”的记录,以便其他人可以将其用作模板,方法是将其加载到具有相同模式的单独数据库中,而不会与同一模型中的其他记录发生冲突。

据我了解 Django 对自然键的支持,这似乎是 NK 的设计目的。我的记录有一个唯一的 name 字段,它也被用作自然键。

所以当我运行时:

from django.core import serializers
from myapp.models import MyModel
obj = MyModel.objects.get(id=123)
serializers.serialize('json', [obj], indent=4, use_natural_keys=True)

我期望这样的输出:

[
{
"model": "myapp.mymodel",
"fields": {
"name": "foo",
"create_date": "2011-09-22 12:00:00",
"create_user": [
"someusername"
]
}
}
]

然后我可以使用 loaddata 将其加载到另一个数据库中,期望它被动态分配一个新的主键。请注意,我的“create_user”字段是 Django 的 auth.User 模型的 FK,它支持自然键,并且输出为自然键而不是整数主键。

然而,生成的实际上是:

[
{
"pk": 123,
"model": "myapp.mymodel",
"fields": {
"name": "foo",
"create_date": "2011-09-22 12:00:00",
"create_user": [
"someusername"
]
}
}
]

这显然会与主键为 123 的任何现有记录发生冲突并覆盖该记录。

解决此问题的最佳方法是什么?我不想将所有自动生成的主键整数字段追溯更改为任何等效的自然键,因为这会导致性能下降以及劳动密集型。

编辑:这似乎是 a bug那是reported ...2 年前...并且在很大程度上被忽略了...

最佳答案

为 2018 年及以后遇到此问题的任何人更新答案。

有一种方法可以通过使用自然键和 unique_together 方法来省略主键。取自Django documentation on serialization :

你可以使用这个命令来测试:

python manage.py dumpdata app.model --pks 1,2,3 --indent 4 --natural-primary --natural-foreign > dumpdata.json ;

自然键序列化

那么如何让 Django 在序列化对象时发出一个自然键呢?首先,您需要添加另一个方法——这次添加到模型本身:

class Person(models.Model):
objects = PersonManager()

first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
birthdate = models.DateField()

def natural_key(self):
return (self.first_name, self.last_name)

class Meta:
unique_together = (('first_name', 'last_name'),)

该方法应该总是返回一个自然键元组——在这个例子中,(名字,姓氏)。然后,当您调用 serializers.serialize() 时,您提供 use_natural_foreign_keys=Trueuse_natural_primary_keys=True 参数:

serializers.serialize('json', [book1, book2], indent=2, use_natural_foreign_keys=True, use_natural_primary_keys=True)

当指定 use_natural_foreign_keys=True 时,Django 将使用 natural_key() 方法将任何外键引用序列化为定义该方法的类型的对象。

当指定 use_natural_primary_keys=True 时,Django 将不会在该对象的序列化数据中提供主键,因为它可以在反序列化期间计算:

    {
"model": "store.person",
"fields": {
"first_name": "Douglas",
"last_name": "Adams",
"birth_date": "1952-03-11",
}
}

关于python - 使用自然键排除 Django 转储数据中的主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9436954/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com