首先,没有一种方法(atm Django 1.9.7)可以 _ 完全* _按照您的意愿使用 发布的原始查询的 Django ORM
表示形式;但是,您可以通过以下方式获得相同的预期结果: _ *_
>>> Topic.objects.annotate( f=Case( When( record__user=johnny, then=F('record__value') ), output_field=IntegerField() ) ).order_by( 'id', 'name', 'f' ).distinct( 'id', 'name' ).values_list( 'name', 'f' )>>> [(u'A', 1), (u'B', None), (u'C', 3)]>>> Topic.objects.annotate(f=Case(When(record__user=may, then=F('record__value')), output_field=IntegerField())).order_by('id', 'name', 'f').distinct('id', 'name').values_list('name', 'f')>>> [(u'A', 4), (u'B', 5), (u'C', 6)]这里是为第一个查询生成的SQL:
>>> print Topic.objects.annotate(f=Case(When(record__user=johnny, then=F('record__value')), output_field=IntegerField())).order_by('id', 'name', 'f').distinct('id', 'name').values_list('name', 'f').query>>> SELECt DISTINCT ON ("payments_topic"."id", "payments_topic"."name") "payments_topic"."name", CASE WHEN "payments_record"."user_id" = 1 THEN "payments_record"."value" ELSE NULL END AS "f" FROM "payments_topic" LEFT OUTER JOIN "payments_record" ON ("payments_topic"."id" = "payments_record"."topic_id") ORDER BY "payments_topic"."id" ASC, "payments_topic"."name" ASC, "f" ASC一些注意事项
- 毫不犹豫地使用原始查询,特别是在性能 最 重要的情况下。而且,有时候这是必须的,因为使用Django的ORM无法获得相同的结果。在其他情况下,您可以这样做,但是偶尔拥有清晰易懂的代码比 这段 代码的性能更为重要。
distinct
此答案中使用带位置参数的参数,仅适用于PostgreSQL atm。在文档中,您可以了解有关条件表达式的更多信息。



