回答

收藏

Django中的完全外部联接

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

如何使用django QuerySet API创建跨M2M关系芯片的完全外部联接的查询?" a# A0 H3 y& ?/ S3 R1 k/ s
它不受支持,欢迎提供有关创建我自己的经理来执行此操作的提示。
2 n( }+ Q5 f! a8 s$ }" N% P: v# ~编辑添加: @ S.Lott:感谢您的启发。应用程序需要使用OUTER
9 j7 g- X" v3 e* J, y# AJOIN。即使它仍然不完整,它也必须生成一个报告,显示输入的数据。我不知道结果将是一个新的类/模型。您的提示将对我有很大帮助。
/ L  O$ ], l; J- _& x3 ?, @                / w% S  r) n3 f: s
解决方案:
# P$ A# j0 ~8 Z0 ^$ k" e                . ~) s9 c, A. a3 h: N/ B& B( q

, u: K( d5 s1 `3 H; b; C
* d% o7 ]( o" e0 L$ x                Django在通常的SQL意义上不支持“联接”-它支持对象导航。
  {, f% B/ H9 O. s- n请注意,关系联接(内部或外部)会创建一个新的实体“类”。在Django中没有定义的一个。因此,没有适当的“结果集”,因为对于返回的内容没有类定义。您能做的最好的事情就是定义一个元组,对于缺少的组合,将在其中填充无。6 A) B  X, w+ K) v- l" D3 W* _
左(或右)外部联接看起来像这样。它创建两个不相交的子集,一个具有一组关联的相关实体,另一个没有。. F" H8 O# A: J8 U+ c: [  @/ E- ~6 Q
for obj in Model1.objects.all():3 w( R1 r1 l- B  ]5 x/ I
    if obj.model2_set().count() == 0:9 v% c" }& y& @; j; a1 ^7 V9 B
        # process (obj, None) -- no Model2 association! n, D0 l. O' J# H2 \5 X! H
    else:  |2 _( i2 ?; Z- O% r8 M, w* V
        for obj2 in obj.model2_set.all():
! n7 {# [: ~2 ]            # process (obj, obj2) -- the "inner join" result( i) u" `- W6 a/ N/ d1 L6 D
“完全”外部联接是没有关系的其余项的并集。
  @4 C3 b1 D! z+ y' E3 Sfor obj2 in Model2.objects.all():
* O& f$ Z8 Q' x* D( p: K8 o    if obj2.model1_set().count() == 0:: p8 [4 _0 l! Q8 j% T7 O/ a
        # process (None, obj2) -- no Model1 association
* A$ W$ f' X8 Y1 U问题始终是,您对这三个不同的对象子集的怪异集合正在做什么处理?9 X9 W9 D$ d% c( t' C+ Q* c
对象数据库的重点是将处理重点放在对象及其关联的对象上。/ T% L# ~$ j$ I9 I& m
原始对象模型中从未存在称为“关系联接”的特殊集合。它是由两个(或多个)原始对象构建的一类新的对象。2 R8 j6 v5 D9 j* f- t  Z
更糟糕的是,外部联接会创建具有多个子类的集合(内部联接,左外部联接和右外部联接)。那东西集合是什么 意思+ q) u% S. w" ?
等一下,情况可能会变得更糟。如果处理过程中包括对缺失属性的检查(即if someObj.anObj2attribute is( y1 Y" M1 q$ F/ w) b/ ~
None:我们本质上是在寻找Model1没有Model2对象关联的项目。嗯……为什么我们将它们放在外部联接中,仅使用if语句对其进行过滤?为什么不做呢?单独的查询和正确处理每个子集?1 h3 F1 d" \% n

4 V0 @4 U* }1 P1 E8 t3 b( }编辑:当您显示“未完成”状态时,它根本不是外部联接。这要简单得多。您需要在视图函数中创建一个(或两个)单独的集合,以显示模板。% C2 e4 \3 H% ^4 i: R
首先,您应该使用状态码,而不要使用是否存在外键。可选的外键没有“理由”-它们在那里或不在那里。状态代码可以提供有用的含义阴影(“不完整”,“错误”,“残破”,“不适用”,“要删除”等)0 K& ^$ f! o( X( v; k# C
errorList1 = Model1.objects.filter( status="Incomplete" )
& ?" l2 [+ C5 Q, merrorList2 = Model2.objects.filter( status="Incomplete" )4 \* |" q' I8 u2 {' f
这两个是完全外部联接的两个非联接部分。然后,您可以在模板中显示这两个错误列表,其中包含适当的列标题和状态代码以及所有内容。
: u# U! Z8 @$ i: r2 B" h您甚至可以将它们放在一个表中,以模仿人们过去看到的旧的完整外部联接报告
) d: }8 h0 b/ U{% for e1 in errorList1 %}& c5 N) }4 W" i  t5 d: i9 ^9 W! L" S
    {% endfor %}" u, ^! `$ {. p' r/ X9 a
    {% for e2 in errorList2 %}* F$ O; p+ [! D% B* G
    {% endfor %}
Model1Model2
e1NULL
NULLe2
' G0 b( f: I/ `- C7 X3 G5 m* L
看起来像一个完整的外部联接报告。没有完整的外部联接。
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则