我通过进行几个查询来构建 Django 模型对象的列表。然后我想删除任何重复项,(所有这些对象的类型都与 auto_increment int PK 相同),但我不能使用 set() 因为它们不可散列。
有没有一种快速简便的方法来做到这一点?我正在考虑使用 dict 而不是以 id 为键的列表。
我通过进行几个查询来构建 Django 模型对象的列表。然后我想删除任何重复项,(所有这些对象的类型都与 auto_increment int PK 相同),但我不能使用 set() 因为它们不可散列。
有没有一种快速简便的方法来做到这一点?我正在考虑使用 dict 而不是以 id 为键的列表。
一般来说,如果可能的话,最好将所有查询合并到一个查询中。IE。
q = Model.objects.filter(Q(field1=f1)|Q(field2=f2))
代替
q1 = Models.object.filter(field1=f1)
q2 = Models.object.filter(field2=f2)
如果第一个查询返回重复的模型,则使用 distinct()
q = Model.objects.filter(Q(field1=f1)|Q(field2=f2)).distinct()
如果您的查询确实无法使用单个命令执行,那么您将不得不求助于使用 dict 或其他答案中推荐的其他技术。如果您在 SO 上发布确切的查询可能会有所帮助,我们可以看看是否可以组合成一个查询。根据我的经验,大多数查询都可以使用单个查询集完成。
有没有一种快速简便的方法来做到这一点?我正在考虑使用 dict 而不是以 id 为键的列表。
如果您被锁定在当前进行多个查询的结构中,这正是我会做的。然后简单地dictionary.values()
返回您的列表。
如果你有更多的灵活性,为什么不使用Q
对象呢?而不是实际进行查询,将每个查询存储在一个Q
对象中并使用按位或(“|”)来执行单个查询。这将实现您的目标并保存数据库命中。
如果您将__hash__
函数添加到模型定义中,则可以使用一个集合,以便它返回 id(假设这不会干扰您在应用程序中可能具有的其他哈希行为):
class MyModel(models.Model):
def __hash__(self):
return self.pk
如果顺序无关紧要,请使用字典。
删除“重复”取决于您如何定义“重复”。
如果您希望每列(PK 除外)都匹配,那将是一件令人头疼的事情——需要进行大量比较。
另一方面,如果您有一些“自然键”列(或一组短列),则可以轻松查询和删除这些列。
master = MyModel.objects.get( id=theMasterKey )
dups = MyModel.objects.filter( fld1=master.fld1, fld2=master.fld2 )
dups.all().delete()
如果您可以识别一些较短的关键字段集以进行重复识别,则效果很好。
编辑
如果模型对象尚未保存到数据库中,您可以在这些键的元组上创建一个字典。
unique = {}
...
key = (anObject.fld1,anObject.fld2)
if key not in unique:
unique[key]= anObject
我用这个:
dict(zip(map(lambda x: x.pk,items),items)).values()