Django为特定外键选择具有重复字段值的行
Posted
技术标签:
【中文标题】Django为特定外键选择具有重复字段值的行【英文标题】:Django select rows with duplicate field values for specific foreign key 【发布时间】:2012-03-04 06:37:14 【问题描述】:again我想在我的模型中搜索重复项,但现在大小写略有不同。
这是我的模型:
class Concept(models.Model):
main_name = models.ForeignKey(Literal)
...
class Literal(models.Model):
name = models.Charfield(...)
concept = models.ForeignKey(Concept)
...
现在我要完成的任务: 选择所有 NOT main_names 的文字,它们具有 same name 用于 same concept。
例如,如果我有文字:
[id:1, name:'test', concept:1, id:2, name:'test', concept:1]
和概念:
[id:1, main_name:1]
那么结果我应该得到 ID=2 的文字。
【问题讨论】:
【参考方案1】:在我看来,您好像想要执行这样的 SQL 查询:
SELECT l1.* FROM myapp_literal AS l1,
myapp_literal AS l2
WHERE l1.id <> l2.id
AND l1.name = l2.name
AND l1.concept = l2.concept
AND l1.id NOT IN (SELECT main_name FROM myapp_concept)
GROUP BY l1.id
好吧,如果查询过于复杂而无法用 Django 的查询语言轻松表达,您可以always ask Django to do a raw SQL query——这可能就是其中一种情况。
【讨论】:
是的,我想我给出的正是我想要的,只是你需要指定 l1.id 而不是 l1.*,否则它将是column must appear in the GROUP BY clause or be used in an aggregate function
你能告诉我我应该写什么删除从 l1 中选择的所有内容吗?
我想我太习惯 mysql 了,allows non-aggregated columns in the SELECT
part of GROUP BY
queries。您非常正确地指出,在大多数数据库中这是不允许的。
要删除与查询匹配的记录,您可以在查询上use Django's delete
method。 Literal.objects.raw('SELECT ...').delete()
之类的东西 但请注意——我写的查询选择了 all 有重复的记录——你可能想删除每个匹配集的除了一个之外的所有记录。【参考方案2】:
如果我理解你想要的问题:
-
所有不是外键到概念的文字对象。
从该集合中,选择名称和概念相同的那些。
如果是这样,我认为这应该可行:
第一部分:
q = Literal.objects.exclude(pk__in=Concept.objects.values_list('id', flat=True))
编辑:
根据 Jan 的出色反馈,我认为对于 #2,您需要使用 raw SQL。
【讨论】:
应该是values_list
,我认为你的第二部分没有做任何事情。你的意思是q.filter(name=F('concept__main_name__name'))
?不过,我不确定这是否是最佳性能。
老实说,我不确定性能部分;但根据我对文档的理解,我认为 F 表达式是正确的。感谢values_list
,已编辑。
它不只是测试文字的名称是否等于它自己的名称(概念相同),这当然适用于所有文字?
好的。我在评论中发布了一个可能的解决方案,并认为它确实确实有效,而不使用原始 SQL 而是外键查找。
是的,我知道必须选择所有非主要文字,这相当简单,我的兴趣是如何执行整个任务。无论如何感谢您的帮助。以上是关于Django为特定外键选择具有重复字段值的行的主要内容,如果未能解决你的问题,请参考以下文章