如何向Django中的模型添加临时字段?

如何向Django中的模型添加临时字段?,django,json,django-models,model,Django,Json,Django Models,Model,我正在开发一个web应用程序,用户可以在其中创建多个相关元素,然后将这些元素保存到数据库中。webapp不知道数据库中的主键是什么,因此它为每个元素分配一个UUID。这些UUID与数据库中的每个元素一起保存。当webapp将数据发送到web服务器以放置在数据库中时,它使用JSON对所有内容进行编码。然后,Web服务器使用序列化程序对JSON进行反序列化。反序列化('JSON',数据)。但是,有些模型具有外键,这些外键在JSON负载中作为对相关元素的UUID的引用而不是数据库ID发送。例如,我们可

我正在开发一个web应用程序,用户可以在其中创建多个相关元素,然后将这些元素保存到数据库中。webapp不知道数据库中的主键是什么,因此它为每个元素分配一个UUID。这些UUID与数据库中的每个元素一起保存。当webapp将数据发送到web服务器以放置在数据库中时,它使用JSON对所有内容进行编码。然后,Web服务器使用
序列化程序对JSON进行反序列化。反序列化('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]"}
不幸的是,这引发了一个异常
fielddoesnotextist:Link在调用
序列化程序时没有名为u'sourceuuid'
的字段。对数据进行反序列化

我想找到一种方法,我可以传递UUID,然后让数据库在保存了适当的部分后填充id,或者在必要时查找它们。我不想在数据库中保存
sourceuuid
targetuuid
,因为保存整数的空间要小得多,而且标记速度也应该更快

所以,我要找的是一个临时字段。我可以实例化和引用它,但它永远不会保存回数据库。有没有关于我将如何创造这样一个东西的想法

更新并提供更多说明

感谢到目前为止的帮助,我知道它们是Python对象,我可以为对象分配任意字段。但是,问题是
序列化程序.反序列化('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'

我需要将虚拟字段设置为实际字段的原因是,反序列化
需要实际字段。

我不知道有这样的临时字段。那太好了:)


但我的建议是:在接收JSON并将其转换为对象的视图中,检查属性。创建一个对象,仅具有“真实”属性(不是外键或M2M)。您可以将任意属性分配给它们(instance.arbitral_attribute=something),但无法获得良好的查找机制(Model.objects.filter(…)。创建所有对象后,再次循环对象,对于每个FK,查找具有链接UUID的对象,并链接到该对象(使用instance.id)。

您可以尝试创建纯python属性,它们不会保存到db。比如:

class Link(models.Model):
    sourceuuid = None

我不确定你到底想做什么。但请记住,Django模型只是Python对象,Python对象是完全动态的。因此,即使模型上没有定义
uuid
字段,执行
obj.uuid=任何操作都是完全有效的。

您可以为存储所需信息的非物化django模型定义外键

为此,在定义了外键(或OnetoOne键)的新模型中,只需放置

class _meta:
    managed = False

为什么不直接使用UID作为主键呢

将主键设置为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)

这是最接近的,但不是你期望的方式。非物化Django模型的ForeignKey仍然会在引用表中添加一列。但是,如果我创建一个完整的非物化子类,并将
sourceuuid
targetuuid
作为新字段,那么我就可以有所作为了。我在一个新的
LinkJSON
类中反序列化,然后映射uuid,然后将字段复制到
Link
类。虽然不漂亮,但还是挺管用的。如果Python有一种简单的方法可以将cast类型转换到基类,那就更好了。我接受这个答案,因为它最接近我想要做的事情。我不得不做一些时髦的子类化,然后创建一个JSONSerializer的子类来处理所有事情,但它现在可以工作了。不幸的是,它已经成为一个非常具体的解决方案,所以我无法将其全部发布到StackOverflow。请参阅我的更新以获得澄清。
反序列化程序
方法拒绝处理任何不是
字段的数据。所以这个方法抛出了一个异常。我已经更新了这个问题的一些细节。我需要它是一个实际的
字段
,否则
反序列化
将引发异常。我正试图避免JSON变得一团糟。这是我可以在代码中引入错误和问题的另一个地方。这会起作用,但这是一个混乱的最后手段。我已经考虑过了,如果我找不到另一种方法,我可能会这么做。然而,UUID在数据库中占据了更大的空间,索引和搜索速度也比Int慢。我们很不清楚您要做什么。。如果你能提供更多关于你任务的细节,也许会有一个好的解决方案