Django 模型 - 如何在事后通过 PK 过滤掉重复值?

发布于 2024-07-17 04:29:06 字数 170 浏览 6 评论 0原文

我通过进行多个查询来构建 Django 模型对象的列表。 然后我想删除任何重复项(所有这些对象都具有 auto_increment int PK 的相同类型),但我不能使用 set() 因为它们不可散列。

有没有一种快速且简单的方法可以做到这一点? 我正在考虑使用字典而不是以 id 作为键的列表。

I build a list of Django model objects by making several queries. Then I want to remove any duplicates, (all of these objects are of the same type with an auto_increment int PK), but I can't use set() because they aren't hashable.

Is there a quick and easy way to do this? I'm considering using a dict instead of a list with the id as the key.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

柏拉图鍀咏恒 2024-07-24 04:29:06

一般来说,如果可能的话,最好将所有查询合并到一个查询中。 IE。

q = Model.objects.filter(Q(field1=f1)|Q(field2=f2))

如果

q1 = Models.object.filter(field1=f1)
q2 = Models.object.filter(field2=f2)

您的查询

q = Model.objects.filter(Q(field1=f1)|Q(field2=f2)).distinct()

确实无法使用单个命令执行,那么您将不得不求助于使用其他答案中推荐的字典或其他技术。 如果您在 SO 上发布了确切的查询,这可能会有所帮助,我们可以看看是否可以将其合并为单个查询。 根据我的经验,大多数查询都可以使用单个查询集来完成。

In general it's better to combine all your queries into a single query if possible. Ie.

q = Model.objects.filter(Q(field1=f1)|Q(field2=f2))

instead of

q1 = Models.object.filter(field1=f1)
q2 = Models.object.filter(field2=f2)

If the first query is returning duplicated Models then use distinct()

q = Model.objects.filter(Q(field1=f1)|Q(field2=f2)).distinct()

If your query really is impossible to execute with a single command, then you'll have to resort to using a dict or other technique recommended in the other answers. It might be helpful if you posted the exact query on SO and we could see if it would be possible to combine into a single query. In my experience, most queries can be done with a single queryset.

海拔太高太耀眼 2024-07-24 04:29:06

有没有一种快速、简单的方法可以做到这一点? 我正在考虑使用字典而不是以 id 作为键的列表。

如果您被锁定在当前进行多个查询的结构中,这正是我会做的。 然后一个简单的 dictionary.values() 将返回您的列表。

如果您有更多的灵活性,为什么不使用 Q 对象呢? 无需实际进行查询,而是将每个查询存储在 Q 对象中,并使用按位或 (“|”) 来执行单个查询。 这将实现您的目标并节省数据库点击量。

Django Q 对象

Is there a quick and easy way to do this? I'm considering using a dict instead of a list with the id as the key.

That's exactly what I would do if you were locked into your current structure of making several queries. Then a simply dictionary.values() will return your list back.

If you have a little more flexibility, why not use Q objects? Instead of actually making the queries, store each query in a Q object and use a bitwise or ("|") to execute a single query. This will achieve your goal and save database hits.

Django Q objects

陌上青苔 2024-07-24 04:29:06

如果将 __hash__ 函数添加到模型定义中,以便它返回 id,则可以使用集合(假设这不会干扰您应用中可能具有的其他哈希行为):

class MyModel(models.Model):

    def __hash__(self):
        return self.pk

You can use a set if you add the __hash__ function to your model definition so that it returns the id (assuming this doesn't interfere with other hash behaviour you may have in your app):

class MyModel(models.Model):

    def __hash__(self):
        return self.pk
怎樣才叫好 2024-07-24 04:29:06

如果顺序不重要,请使用字典。

If the order doesn't matter, use a dict.

梦亿 2024-07-24 04:29:06

删除“重复项”取决于您如何定义“重复项”。

如果您希望每一列(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

Remove "duplicates" depends on how you define "duplicated".

If you want EVERY column (except the PK) to match, that's a pain in the neck -- it's a lot of comparing.

If, on the other hand, you have some "natural key" column (or short set of columns) than you can easily query and remove these.

master = MyModel.objects.get( id=theMasterKey )
dups = MyModel.objects.filter( fld1=master.fld1, fld2=master.fld2 )
dups.all().delete()

If you can identify some shorter set of key fields for duplicate identification, this works pretty well.


Edit

If the model objects haven't been saved to the database yet, you can make a dictionary on a tuple of these keys.

unique = {}
...
key = (anObject.fld1,anObject.fld2)
if key not in unique:
    unique[key]= anObject
南…巷孤猫 2024-07-24 04:29:06

我用这个:

dict(zip(map(lambda x: x.pk,items),items)).values()

I use this one:

dict(zip(map(lambda x: x.pk,items),items)).values()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文