如何在django中使用子查询?

栏目: Python · 发布时间: 6年前

内容简介:http://stackoverflow.com/questions/14331224/how-to-use-subquery-in-django

我想收到每个客户的最新购买清单,按日期排序.

以下查询除了日期以外我想做什么

Purchase.objects.all().distinct('customer').order_by('customer', '-date')

它产生一个查询,如:

SELECT DISTINCT ON "shop_purchase.customer_id" "shop_purchase.id" "shop_purchase.date" FROM "shop_purchase" ORDER BY "shop_purchase.customer_id" ASC, "shop_purchase.date" DESC;

由于DISTINCT ON,我被迫使用customer_id作为第一个ORDER BY表达式.

我想按日期排序,所以我真正需要的查询应该是这样的:

SELECT * from (
  SELECT DISTINCT ON "shop_purchase.customer_id" "shop_purchase.id" "shop_purchase.date" FROM "shop_purchase" ORDER BY "shop_purchase.customer_id" ASC, "shop_purchase.date" DESC;
) as result ORDER BY date DESC;

我不想使用 python 进行排序,因为我仍然需要页面限制查询.数据库中可以有数万行.

实际上它目前正在python中排序,并导致非常长的页面加载时间,所以这就是为什么我试图解决这个问题.

基本上我想要这样的东西 http://stackoverflow.com/a/9796104/242969 .可以用django查询表达它,而不是编写原始的SQL?

实际的模型和方法有几页长,但这里是上面查询所需的一组模型.

class Customer(models.Model):
  user = models.OneToOneField(User)

class Purchase(models.Model):
  customer = models.ForeignKey(Customer)
  date = models.DateField(auto_now_add=True)
  item = models.CharField(max_length=255)

如果我有数据,如:

Customer A - Purchase(item=Chair, date=January), Purchase(item=Table, date=February)
Customer B - Purchase(item=Speakers, date=January), Purchase(item=Monitor, date=May)
Customer C - Purchase(item=Laptop, date=March), Purchase(item=Printer, date=April)

我想要提取以下内容:

Purchase(item=Monitor, date=May)
Purchase(item=Printer, date=April)
Purchase(item=Table, date=February)

每个客户的列表中至多有一个购买.购买是每个客户最新的.按最新日期排序.

此查询将能够提取:

SELECT * from (
  SELECT DISTINCT ON "shop_purchase.customer_id" "shop_purchase.id" "shop_purchase.date" FROM "shop_purchase" ORDER BY "shop_purchase.customer_id" ASC, "shop_purchase.date" DESC;
) as result ORDER BY date DESC;

我试图找到一种不必使用原始 SQL 实现此结果的方法.

这可能不是你正在寻找的,但它可能会让你更近.看看 Django’s annotate

.

这是一个可能有帮助的例子:

from django.db.models import Max
  Customer.objects.all().annotate(most_recent_purchase=Max('purchase__date'))

这将为您提供您的客户模型列表,其中每个都将有一个新的属性称为“most_recent_purchase”,并将包含他们上次购买的日期.生成的sql看起来像这样:

SELECT "demo_customer"."id", 
       "demo_customer"."user_id", 
       MAX("demo_purchase"."date") AS "most_recent_purchase"
FROM "demo_customer"
LEFT OUTER JOIN "demo_purchase" ON ("demo_customer"."id" = "demo_purchase"."customer_id")
GROUP BY "demo_customer"."id",
         "demo_customer"."user_id"

另一个选择是添加一个属性到您的客户模型,看起来像这样:

@property
  def latest_purchase(self):
    return self.purchase_set.order_by('-date')[0]

您显然需要处理此属性中没有任何购买的情况,这可能不会很好(因为您将为每个客户运行一个查询以获得最新的购买).

过去我已经使用了这两种技术,并且在不同的情况下都能正常工作.我希望这有帮助.祝你好运!

http://stackoverflow.com/questions/14331224/how-to-use-subquery-in-django


以上所述就是小编给大家介绍的《如何在django中使用子查询?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数字乌托邦

数字乌托邦

尼古拉斯•卡尔 / 姜忠伟 / 中信前沿出版社 / 2018-5 / 69.00

当下,技术与我们的关系变得越来越紧密不可分割,特别是智能手机等设备的出现,带给整个人类社会一场彻底的变革。的确,智能手机上的各种应用程序让我们的工作生活无比便利:社交媒体让我们能够和他人实时保持联络并传输信息,不再受时间、地点的限制;搜索引擎通过精准的算法将我们所需要的信息整合推送至屏幕上,让我们毫不费力就看到自己想要的;地图软件为我们的出行提供了更多路线选择,甚至可以使用语音导航,帮助我们顺利到......一起来看看 《数字乌托邦》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具