我正在开发一个Web应用程序,用户可以在其中创建多个相关元素,然后将这些元素保存到数据库中。 webapp不知道主键在数据库中的含义,因此它为每个元素分配一个UUID。这些UUID与数据库中的每个元素一起保存。当webapp将数据发送到Web服务器以放入数据库时,它使用JSON对所有内容进行编码。然后,网络服务器使用serializers.deserialize('json', DATA)
对JSON进行反序列化。但是,某些模型具有外键,这些外键在JSON有效内容中作为对相关元素的UUID而不是数据库ID的引用发送。例如,我们可能有一个简单的链接对象:
class Link(models.Model):
uuid = models.CharField(max_length=32)
source = models.ForeignKey(Node, related_name='source')
target = models.ForeignKey(Node, related_name='target')
如果源的id值为2且目标的id值为12,则会将其序列化为JSON,如下所示:
{"uuid": "[some long uuid]",
"source": 2,
"target": 12}
但是,因为在这种情况下我们不知道源和目标的数据库ID,可能是因为它们还没有设置,我能做的最好就是传递UUID这样:
{"uuid": "[some long uuid]",
"sourceuuid": "[uuid of source]",
"targetuuid": "[uuid of target]"}
不幸的是,当我在数据上调用FieldDoesNotExist: Link has no field named u'sourceuuid'
时,这会引发serializers.deserialize
的例外。
我想找到一种方法,我可以传递UUID,然后在保存适当的部分或在必要时查找它们之后让数据库填入id。我不想在数据库中保存sourceuuid
和targetuuid
,因为保存整数的空间要少得多,而且指标也应该更快。
所以,我正在寻找的是一个临时领域。我可以实例化和引用的,但它永远不会保存回数据库。关于如何制作这样的东西的任何想法?
更新更清晰
感谢您的帮助到目前为止,我知道它们是Python对象,我可以为对象分配任意字段。但是,问题是serializers.deserialize('json', INDATA)
会抛出错误。
作为参考,这里是反序列化程序喜欢的一大块JSON,它有外键及其ID:
ser='''[{"pk": 1, "model": "myapp.link",
"fields": {"uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"source": 2,
"target": 12}}]'''
serializer.deserialize('json',ser)
但是,我能提供的是:
ser='''[{"pk": 1, "model": "myapp.link",
"fields": {"uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
"sourceuuid": "11111111-2222-3333-4444-555555555555",
"targetuuid": "66666666-7777-8888-9999-000000000000"}}]'''
serializer.deserialize('json',ser)
FieldDoesNotExist: Link has no field named u'sourceuuid'
我需要将虚拟字段作为实际字段的原因是因为deserialize
需要实际字段。
答案 0 :(得分:2)
我不确定你到底想要做什么。但请记住,Django模型只是Python对象 - 而Python对象完全是动态的。因此,即使模型上没有定义obj.uuid = whatever
字段,也可以uuid
完全有效。
答案 1 :(得分:1)
您可以为非物化django模型定义一个外键,用于存储您需要的信息。
为此,在定义了外键(或OnetoOne Key)的新模型中,只需放置
class _meta:
managed = False
答案 2 :(得分:0)
我不知道这样一个临时领域。这将是很好的:))
但我的建议是:在接收JSON并将其转换为对象的视图中,检查属性。您创建一个对象,只有“真实”属性(不是外键或M2M)。您可以为它们分配任意属性(instance.arbitrary_attribute = something),但是您将无法获得良好的查找机制(Model.objects.filter(...))。创建所有对象后,再次循环遍历对象,并为每个FK查找具有链接UUID的对象,并链接到该对象(使用instance.id)。
答案 3 :(得分:0)
您可以尝试创建普通的python属性,它们不会保存到db。像:
class Link(models.Model):
sourceuuid = None
答案 4 :(得分:0)
为什么不直接使用UIDS作为主键?
将primary_key设置为True
class Node(models.Model):
uuid = models.CharField(max_length=32, primary_key=True)
[...]
class Link(models.Model):
uuid = models.CharField(max_length=32, primary_key=True)