我有两个这样的模型:
class Store(models.Model):
name = models.CharField(max_length=255)
class Order(models.Model):
store = models.ForeignKey(Store)
date = models.DateTimeField(auto_now_add=True)
success = models.BooleanField()
我想过滤最新订单成功的Store
模型中的所有记录,即success == True
。
虽然看起来非常简单,但我在解决如何使用ORM查询系统完成此任务时遇到了问题。
有任何帮助吗?感谢。
答案 0 :(得分:2)
我的方法是:做2个列表,第一个用(id_store,last_success_date)元组,第二个用(id_store,last_date)元组:
l_succ = stores.objects.filter(
order__success = True
).annotate(
last_success=Max('order__date')
).value_list (
'id', 'last_success'
)
#l_succ = [ (1, '1/1/2011'), (2, '31/12/2010'), ... ] <-l_succ result
l_last = stores.objects.annotate(
last_date=Max('order__date')
).value_list (
'id', 'last_date'
)
#l_last = [ (1, '1/1/2011'), (2, '3/1/2011'), ... ] <-l_last result
然后将商店ID用于最后数据和上次成功日期等于的商店,并且您有查询:
store_success_ids = [ k[0] for k in l_succ if k in l_last ]
#store_success_ids = [1, 5, ... ] <-store_success_ids result
#Cast l_last to dictionary to do lookups if you have a lot of stores.
result = Store.objects.filter( pk__in = store_success_ids)
这似乎是一个优雅的解决方案,只有四行代码用于复杂的查询(但只需要简单的requeriment)。免责声明,未经测试。
答案 1 :(得分:1)
这只是一个想法,所以如果我完全错了,不要打败我:) 我以为你可以这样做:
# first annotate latest order to Store which returns new queryset, filter new qs
# by success = True
stores = Store.objects.annotate(Max('order__date')).filter(order__success=True)
老实说这是未经测试的。
答案 2 :(得分:0)
您可以在一个查询中执行此操作。
使用QuerySets的.extra()功能编写如下所示的SQL:
Store.objects.extra(where=['id in (select store_id from order where success = true)'])
答案 3 :(得分:0)
这种方法对你有用吗?遍布所有商店并获取每个商店的最新成功(如果存在)。
我最初的想法是不正确的:
latest_successes = []
store_objects = Store.objects.all()
for store_obj in store_objects:
try:
latest_success = Order.objects.filter(store=store_obj).filter(success=True).order_by('-date')[0]
except IndexError:
pass
else:
latest_successes.append(latest_success)
根据@demalexx的实体评论进行编辑
latest_successes = []
store_objects = Store.objects.all()
for store_obj in store_objects:
try:
is_latest_success = store_obj.order_set.order_by('-date')[0].success
except IndexError:
pass
else:
latest_successes.append(store_obj)