如何在django中合并两个查询并从两个不相关的表中选择不同

时间:2015-06-27 01:02:14

标签: mysql django django-queryset

我正在使用MySQL后端在Django(1.8)中工作。我有两个不相关的表,我想查询。结果是每个表中两列的串联。我想合并结果,对它们进行排序并选择不同。为了举例,我们假设我有tableA和tableB,它们都有first_name和last_name列。每个cloumn标题都引用其中的表(例如first_name_A)。目前我正在对每个表运行查询并使用sorted(chain(queryA,queryB))将它们放在一起。当我尝试在模板中的for循环中引用结果时出现问题。

Codewise我有这个:

views.py

queryA = tableA.objects.order_by('first_name_A', 'last_name_A').values('first_name_A', 'last_name_A').distinct()
queryB = tableB.objects.order_by('first_name_B', 'last_name_B').values('first_name_B', 'last_name_B').distinct()

query = sorted(chain(queryA, queryB))

return render_to_response('results.html', {'queries': query})

html

<div>
{% for query in queries %}
    <tr>
        <td>{{ query.first_name_A }} {{ query.last_name_A }}</td>
    </tr>
{% endfor %}
</div>

上面的html显然只返回tableA中的名字和姓氏。这些是有序和不同的,但不包括tableB的信息。由于每个表中的列具有不同的标题,除了值(而不是键)之外没有其他属性,我如何合并它们,排序和选择不同的组合?或者我应该只重命名列以删除表引用?

2 个答案:

答案 0 :(得分:1)

您可以使用extra()修饰符指定其他名称。

queryA = tableA.extra(select={'alias' : 'first_name_A'}).order_by('first_name_A').values('alias').distinct()
queryB = tableB.extra(select={'alias' : 'first_name_B'}).order_by('first_name_B').values('alias').distinct()

django文档不鼓励使用extra,但似乎并不是在查询集中创建别名的简单方法。 This ticket表明这可能会在未来发生变化。最后一条评论描述了一种使用F表达式和annotate的替代方法,该方法适用于django v1.8

答案 1 :(得分:0)

我已经解决了,但我不确定它是最pythonic(也不正确)的方式。如果有人有任何更好的建议,请告诉我。

<强> views.py

        queryA = tableA.objects.order_by('first_name_A','last_name_A').values('first_name_A', 'last_name_A').distinct()
        queryB = tableB.objects.order_by('first_name_B','last_name_B').values('first_name_B', 'last_name_B').distinct()


        chain_query = sorted(chain(queryA, queryB))


        valueList = []


        for q in chain_query:
            wholeName = ' '.join(q.values())
            valueList.append(wholeName)


        query = sorted(set(valueList))  

        return render_to_response('results.html', {'queries': query})

<强> HTML

    {% for query in queries %}
    <tr>
        <td>{{ query }}</td>
    </tr>
    {% endfor %}