用django的orm模拟内连接,没有显式的外键

时间:2014-03-20 18:26:47

标签: python django orm

我有两个模型,Widgets和Cases。表之间没有明确的关系(没有外键)。表格内容如下所示:

Widgets                              Cases                          
|----+--------+-------+---------|    |----+------+-------+---------|
| id | color  | spots | stripes |    | id | size | spots | stripes |
|----+--------+-------+---------|    |----+------+-------+---------|
|  1 | blue   |     2 |       6 |    |  1 | s    |     2 |       1 |
|  2 | blue   |     3 |      10 |    |  2 | m    |     2 |       6 |
|  3 | blue   |     2 |       1 |    |  3 | l    |     3 |      10 |
|  4 | green  |    20 |       7 |    |  4 | xl   |    20 |       7 |
|  5 | purple |     3 |      10 |    |----+------+-------+---------|
|----+--------+-------+---------|

我希望获得与任何一个蓝色小部件具有相同数量的斑点和条纹的所有情况。使用SQL,它看起来像:

SELECT Cases.id
FROM Cases
    INNER JOIN Widgets 
    ON     Cases.spots = Widgets.spots 
       AND Cases.stripes = Widgets.stripes
WHERE Widgets.color = 'blue';

哪个应返回ID:[1, 2, 3]

我试图使用django ORM获得相同的结果。我提出的是:

selected_widgets = Widgets.objects.filter(color='blue').values('spots', 'stripes')
associated_cases = [Cases.objects.get(spots=v['spots'], stripes=v['stripes']) 
                        for v in selected_widgets]

假设spotsstripes始终唯一地标识案例,因此.get调用不是问题。这个解决方案看起来效率仍然非常低,为每个小部件单独调用数据库,而sql只进行内连接。有没有一种简单的方法可以在使用django ORM的同时减少数据库的运行次数?

1 个答案:

答案 0 :(得分:1)

这可能是使用.raw()方法的绝佳时机;您可以指定确切的SQL并将结果作为正常的Django对象结果列表。