经过多次试验和错误并检查了类似的问题之后,我认为值得将所有细节都询问一下。
这是一个简单的模型。假设我们有一个Book模型和一个Reserve模型,其中包含每个Book的预订数据。
class Book(models.Model):
title = models.CharField(
'Book Title',
max_length=50
)
name = models.CharField(
max_length=250
)
class Reserve(models.Model):
book = models.ForeignKey(
Book,
on_delete=models.CASCADE
)
reserve_date = models.DateTimeField()
status = models.CharField(
'Reservation Status',
max_length=5,
choices=[
('R', 'Reserved'),
('F', 'Free')
]
)
我向模型添加了一本书和两个保留记录:
from django.utils import timezone
book_inst = Book(title='Book1')
book_inst.save()
reserve_inst = Reserve(book=book_inst, reserve_date=timezone.now(), status='R')
reserve_inst.save()
reserve_inst = Reserve(book=book_inst, reserve_date=timezone.now(), status='F')
reserve_inst.save()
我的目标是获取每本书最后预订的数据。基于其他问题,我明白了这一点:
from django.db.models import F, Q, Max
reserve_qs = Reserve.objects.values(
'book__title'
)
reserve_qs
现在具有每本书的最后一个动作,但是当我添加.value()
它时,它将忽略分组并返回所有记录。
我也尝试用F过滤:
Reserve.objects.values(
'book__title'
).annotate(
last_action=Max('reserve_date')
).values(
).filter(
reserve_date=F('last_action')
)
我正在使用Django 3和SQLite。
通过使用另一个过滤器,您将破坏该GROUP BY
机制。但是,您可以通过以下方式简单地获取最后的预订:
from django.db.models import F, Max
Reserve.objects.filter(
book__title='Book1'
).annotate(
book_title=F('book__title'),
last_action=Max('book__reserve__reserve_date')
).filter(
reserve_date=F('last_action')
)
或所有书籍:
from django.db.models import F, Max
qs = Reserve.objects.annotate(
book_title=F('book__title'),
last_action=Max('book__reserve__reserve_date')
).filter(
reserve_date=F('last_action')
).select_related('book')
因此,我们将在此处计算该书的最大值。由于我们在此加入同一张桌子,因此我们可以正确分组。
这将检索Book
过滤后保留的所有的所有最后保留。通常情况下,每个1个Book
。但是,如果存在多个,Book
其中多个Reservation
时间戳完全相同,则将返回多个。
因此,我们可以例如通过以下方式打印预订:
for q in qs:
print(
'Last reservation for {} is {} with status {}',
q.book.title,
q.reserve_date,
q.status
)
但是,对于单本书,最好仅获取Book
对象并返回.latest(..)
[Django-doc]重新搜索:
Book.objects.get(title='Book1').reserve_set.latest('reserve_date')
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句