django的全外连接

时间:2008-10-31 09:46:56

标签: sql django outer-join

如何使用django QuerySet API为M2M关系芯片的完整外部联接创建查询?

这是不受支持的,欢迎创建我自己的经理的一些暗示。

编辑添加: @美国洛特: 谢谢你的启示。 OUTER JOIN的需求来自应用程序。它必须生成一个报告,显示输入的数据,即使它仍然不完整。 我不知道结果将是一个新的类/模型。你的提示会对我有所帮助。

2 个答案:

答案 0 :(得分:11)

Django不支持通常的SQL意义上的“连接” - 它支持对象导航。

请注意,关系连接(内部或外部)会创建一个新的“实体”类。一个在Django中没有定义的。所以没有正确的“结果集”,因为你没有对你得到的东西进行类定义。你能做的最好的事情就是定义一个元组,它将用缺少的组合打包。

左(或右)外连接看起来像这样。它创建了两个不相交的子集,即具有相关实体集的那些子集,以及那些没有相关实体的子集。

for obj in Model1.objects.all():
    if obj.model2_set().count() == 0:
        # process (obj, None) -- no Model2 association
    else:
        for obj2 in obj.model2_set.all():
            # process (obj, obj2) -- the "inner join" result

“完整”外部联接是没有关系的其余项目的联合。

for obj2 in Model2.objects.all():
    if obj2.model1_set().count() == 0:
        # process (None, obj2) -- no Model1 association

问题始终是,您正在使用这三个不同对象子集的奇怪集合进行哪些处理?

对象数据库的要点是将处理集中在对象及其关联对象上。

称为“关系连接”的特殊集合永远不会出现在原始对象模型中。它是由两个(或更多)原始对象构建的新类对象。

更糟糕的是,外连接创建了一个包含多个子类的集合(内连接,左外连接和右外连接)。这些东西意味着是什么?

等等,它会变得更糟。如果处理包括检查缺少的属性(即if someObj.anObj2attribute is None:我们实际上是在寻找没有Model1对象关联的Model2项。嗯...为什么我们把它们放在外连接,只是使用if语句过滤它们?为什么不单独执行单独的查询并正确处理每个子集?


编辑:当您显示“不完整”状态时,它根本不是外部联接。它简单得多。您需要在视图函数中创建一个(或两个)单独的集合,以便显示模板。

首先,您应该使用状态代码,而不是是否存在外键。可选的外键没有“原因” - 它们是否在那里。状态代码可以提供有用的含义(“不完整”,“错误”,“破坏”,“不适用”,“待删除”等)。

errorList1 = Model1.objects.filter( status="Incomplete" )
errorList2 = Model2.objects.filter( status="Incomplete" )

这两个是完整外连接的两个非连接部分。然后,您可以在模板中显示这两个错误列表,其中包含相应的列标题和状态代码以及所有内容。

您甚至可以将它们放入单个表格中,以模仿人们过去看到的旧的完整外部联接报告

<table>
    <tr><th>Model1</th><th>Model2</th></tr>
    {% for e1 in errorList1 %}
    <tr><td>e1</td><td>NULL</td></tr>
    {% endfor %}
    {% for e2 in errorList2 %}
    <tr><td>NULL</td><td>e2</td></tr>
    {% endfor %}
</table>

看起来像是一个完整的外部联接报告。没有完整的外部联接。

答案 1 :(得分:1)

我和其合作的人之一Colin写了一篇关于在Django中进行自定义连接的帖子:

http://www.caktusgroup.com/blog/2009/09/28/custom-joins-with-djangos-queryjoin/

您可能会在那里找到有用的东西!