回答

收藏

Django中的完全外部联接

技术问答 技术问答 265 人阅读 | 0 人回复 | 2023-09-14

如何使用django QuerySet API创建跨M2M关系芯片的完全外部联接的查询?$ z- Y) E  Q2 z
它不受支持,欢迎提供有关创建我自己的经理来执行此操作的提示。. O. ^7 H! J8 s- F7 `
编辑添加: @ S.Lott:感谢您的启发。应用程序需要使用OUTER
/ b8 h% E. r6 N) V. ZJOIN。即使它仍然不完整,它也必须生成一个报告,显示输入的数据。我不知道结果将是一个新的类/模型。您的提示将对我有很大帮助。5 [6 h* r6 D8 s2 K, y
                & w0 {2 }& M' x3 T( p
解决方案:7 |( n! Y: b* P8 H
               
$ R" K. @( d% [- B6 I% N. s; j. q& {! v0 t( s0 o& }: x& N+ Y
. c9 |' i' }: ]' c& n. S- T& t
                Django在通常的SQL意义上不支持“联接”-它支持对象导航。
7 t& c+ z, f: s! A6 k请注意,关系联接(内部或外部)会创建一个新的实体“类”。在Django中没有定义的一个。因此,没有适当的“结果集”,因为对于返回的内容没有类定义。您能做的最好的事情就是定义一个元组,对于缺少的组合,将在其中填充无。
' g: F4 a5 o' {; S5 T: {! c! z左(或右)外部联接看起来像这样。它创建两个不相交的子集,一个具有一组关联的相关实体,另一个没有。1 P8 s' ^; e4 q; w  j% O3 W
for obj in Model1.objects.all():
+ H4 m6 L3 H0 W4 b/ r+ [* Q+ T    if obj.model2_set().count() == 0:
- X: _7 s  ]2 l) X$ p' o        # process (obj, None) -- no Model2 association. p! I3 n& F8 j& p, B+ _. Z& m
    else:5 {5 L. ?2 D6 g  S1 [  T
        for obj2 in obj.model2_set.all():" Y" T; v7 I, X+ A3 \
            # process (obj, obj2) -- the "inner join" result
3 O0 ~+ F" b" ?+ Z6 ]“完全”外部联接是没有关系的其余项的并集。
0 Y/ Z! Z6 N2 b3 O9 z1 x* R$ cfor obj2 in Model2.objects.all():7 h  w% m: L/ O# p  W
    if obj2.model1_set().count() == 0:% u, V3 i, \! g7 q- g1 x5 i/ I
        # process (None, obj2) -- no Model1 association+ M! P8 H' E3 @& Q" F# R: Q& p; Y
问题始终是,您对这三个不同的对象子集的怪异集合正在做什么处理?
/ K4 |2 K: o1 }对象数据库的重点是将处理重点放在对象及其关联的对象上。$ `2 I+ O# F& _* y# `; p- N
原始对象模型中从未存在称为“关系联接”的特殊集合。它是由两个(或多个)原始对象构建的一类新的对象。0 S! \7 L$ \) ~  `0 `' ^4 s
更糟糕的是,外部联接会创建具有多个子类的集合(内部联接,左外部联接和右外部联接)。那东西集合是什么 意思
; U7 H5 P7 w& O7 Y. v1 q$ Q5 H等一下,情况可能会变得更糟。如果处理过程中包括对缺失属性的检查(即if someObj.anObj2attribute is6 D4 a: R4 q7 ]
None:我们本质上是在寻找Model1没有Model2对象关联的项目。嗯……为什么我们将它们放在外部联接中,仅使用if语句对其进行过滤?为什么不做呢?单独的查询和正确处理每个子集?  O" `! G8 z( s% I

/ P& Q. ~1 S) O: \. \: P编辑:当您显示“未完成”状态时,它根本不是外部联接。这要简单得多。您需要在视图函数中创建一个(或两个)单独的集合,以显示模板。
+ w, y. m9 c8 n首先,您应该使用状态码,而不要使用是否存在外键。可选的外键没有“理由”-它们在那里或不在那里。状态代码可以提供有用的含义阴影(“不完整”,“错误”,“残破”,“不适用”,“要删除”等)
/ s# A+ B: b2 C/ L2 y' l7 B/ o' werrorList1 = Model1.objects.filter( status="Incomplete" )' g1 h- p$ {. G5 T- g
errorList2 = Model2.objects.filter( status="Incomplete" )
" [" \( t" O6 }" Q7 [" H$ f这两个是完全外部联接的两个非联接部分。然后,您可以在模板中显示这两个错误列表,其中包含适当的列标题和状态代码以及所有内容。  L7 O) K) B3 ?$ D! Y
您甚至可以将它们放在一个表中,以模仿人们过去看到的旧的完整外部联接报告+ [7 o+ }) @! b. |3 f# r- E
{% for e1 in errorList1 %}$ ^% O/ W% b5 o+ F: ]6 g
    {% endfor %}9 w7 i9 U# ~2 s2 S/ X
    {% for e2 in errorList2 %}# a$ P% F5 ?8 |# `& a$ F, E2 R
    {% endfor %}
Model1Model2
e1NULL
NULLe2

& y) }7 i- L$ Q! n1 d看起来像一个完整的外部联接报告。没有完整的外部联接。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则