2008-10-31 90 views
8

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

这不被支持,关于创建我自己的经理来做这件事的一些暗示将受到欢迎。

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

回答

11

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

请注意,关系连接(内部或外部)会创建一个新的“实体类”。一个在Django中没有定义的人。所以没有适当的“结果集”,因为没有类定义你回头的东西。你可以做的最好的事情是定义一个元组,这个元组将会与None一起被包含在缺失的组合中。

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

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语句过滤它们?为什么不只是做单独的查询AMD过程中的每个子集适当


编辑:。当你呈现“未完成”状态,它不是一个外连接在所有它的简单得多,您需要创建一个或两个单独的集合在你的视图函数中用于你的模板显示

首先,你应该使用状态码,而不是存在或取消外键的作用。可选的外键没有“理由” - 它们在那里或不在那里。状态代码可以提供有用的意义阴影(“不完整”,“错误”,“中断”,“不适用”,“待删除”等)。)

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> 

看起来像一个完全外部报告的人加入报告中。没有完整的外连接。

+0

你说得对。我将编写一个视图,计算python中我的“FULL OUTER JOIN”的必要表,然后将结果传递给模板进行渲染。 谢谢。 – Ber 2008-10-31 15:05:40