我理解,在单例情况下,您可以执行以下操作:
spam == eggs
如果 spam
和 eggs
是具有所有相同属性值的同一个类的实例,则它将返回 True
. 在Django模型中,这很自然,因为模型的两个独立实例将不会相同,除非它们具有相同的 .pk
值 .
这样做的问题是,如果对实例的引用具有已经由中间件在某个地方更新的属性,并且它没有尝试将其添加到另一个持有对同一模型的实例的引用的变量,则它将返回 False
当然因为它们对某些属性有不同的值 . 显然我不需要像singleton这样的东西,但我想知道是否有一些官方的Djangonic(ha,一个新词)方法来检查这个,或者我是否应该只检查 .pk
值是否相同:
spam.pk == eggs.pk
我很抱歉,如果这是浪费时间,但似乎可能有一种方法可以做到这一点,而我想念的是,如果我找不到它,我会后悔的 .
更新(02-27-2015)
你应该忽略这个问题的第一部分,因为你不应该将单身人士与 ==
进行比较,而应该与 is
进行比较 . 单身者真的与这个问题毫无关系 .
7 回答
正如orokusaki评论,“如果两个实例都没有主键,它将始终返回true” . 如果你想要这个,你可以像这样扩展你的模型:
仅供记录,比较:
如果它们中的任何一个可能是由Model.objects.raw()查询创建的延迟模型实例或者应用于“普通”QuerySet的.defer(),则是危险的 .
我在这里提供了更多细节:Django QuerySet .defer() problem - bug or feature?
来自django documentation:
要比较两个模型实例,只需使用标准的Python比较运算符,double等号:== . 在幕后,比较两个模型的主键值 .
spam.pk == eggs.pk
是一个很好的方法 .您可以将
__eq__
添加到您的模型中,但我会避免这种情况,因为它会让人感到困惑,因为==
可能在不同的上下文中表示不同的内容,例如我可能希望==
表示内容相同,id可能不同,所以再次最好的方法是编辑:btw在django 1.0.2模型类中定义
__eq__
为这似乎与spam.pk == eggs.pk相同
pk
是使用_get_pk_val
的属性所以我不明白为什么spam == eggs
不起作用?从Django 2.1.2开始,模型实例相等的源代码是this:
也就是说,如果来自相同的数据库表并且具有相同的主键,则两个模型实例是相等的 . 如果主键是
None
,则它们're only equal if theyr'是同一个对象 .(所以回到OP的问题,只需比较实例就可以了 . )
您可以定义Class'
__eq__
方法来解决该行为:http://docs.python.org/reference/datamodel.html
如果两个模型实例比较相同,如果它们具有不同的属性,那将会很奇怪 . 大部分时间都是不可取的 .
你想要的是一个特例 . 比较
spam.pk == eggs.pk
是个好主意 . 如果还没有pk
,因为如果某些属性不同,它们很难定义哪些实例是"really"相同 .如何在创建实例时向实例添加自定义属性,例如:
spam.myid=1
,eggs.myid=2
这种方式在代码中的某些时候
spamcopy1.seasoning=ketchup
和spamcopy2.seasoning=blackpepper
可以比较它们的myid
属性,看它们是否真的是"same"垃圾邮件 .