Django comparing model instances for equality
我理解,在单例情况下,您可以执行以下操作:
1 | spam == eggs |
如果
问题在于,如果对一个实例的引用具有一些属性,这些属性已经在某个地方被中间件更新,并且还没有保存,并且您试图将其保存到另一个变量中,该变量包含对同一个模型的实例的引用,那么它将返回
1 | spam.pk == eggs.pk |
如果这是浪费时间的话,我很抱歉,但似乎有一种方法可以做到这一点,如果我找不到的话,我会后悔的。
更新(2015年2月27日)你应该忽略这个问题的第一部分,因为你不应该将单件货物与
来自Django文档:
要比较两个模型实例,只需使用标准的python比较运算符,双等号:==。在幕后,比较两个模型的主键值。
你可以在你的模型中添加
1 | spam.pk == eggs.pk |
编辑:django 1.0.2模型类中的btw将
1 2 | def __eq__(self, other): return isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val() |
这似乎与spam.pk==eggs.pk相同,因为
从Django 2.1.2开始,模型实例等式的源代码如下:
1 2 3 4 5 6 7 8 9 | def __eq__(self, other): if not isinstance(other, Model): return False if self._meta.concrete_model != other._meta.concrete_model: return False my_pk = self.pk if my_pk is None: return self is other return my_pk == other.pk |
也就是说,如果两个模型实例来自同一个数据库表并且具有相同的主键,那么这两个模型实例是相等的。如果其中一个主键是
(所以回到OP的问题,简单地比较实例就可以了。)
您可以定义类"
http://docs.python.org/reference/datamodel.html网站
只是为了记录,比较一下:
1 | spam == eggs |
如果它们中的任何一个可能是由model.objects.raw()查询或由应用于"normal"查询集的.defer()创建的延迟模型实例,则是危险的。
我把更多的细节放在这里:django queryset.defer()问题-bug还是特性?
正如Orokusaki所说,"如果两个实例都没有主键,它将始终返回true"。如果您希望这样做,可以像这样扩展您的模型:
1 2 3 4 5 6 | def __eq__(self, other): eq = isinstance(other, self.__class__) and self._get_pk_val() == other._get_pk_val() if eq and self._get_pk_val() is None: return id(self) == id(other) return eq |
如果两个模型实例具有不同的属性,将它们比较为相等,这会很奇怪。大多数时候这是不受欢迎的。
你想要的是一个特例。比较
在创建实例时,如何向其添加自定义属性,例如:江户十一〔11〕、江户十一〔12〕。
在代码中的某个时候,当