![](/img/trans.png)
[英]Improving efficiency of QuerySet filter by most recent record of a certain “type” (attribute)
[英]Django queryset filter for most recent in the past and all in the future
我有這樣的模型ContentBuild
& ContentBuildDeviceGroupLink
:
# models.py
class ContentBuild(models.Model):
content_build_uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
class ContentBuildDeviceGroupLink(models.Model):
uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, db_index=True)
content_build_uuid = models.ForeignKey(ContentBuild, on_delete=models.CASCADE, related_name='content_build_deploy')
group_uuid = models.ForeignKey(DeviceGroup, on_delete=models.CASCADE)
preload_date = UnixDateTimeField()
release_date = UnixDateTimeField()
我想返回過去帶有release_date
最新ContentBuildDeviceGroupLink
對象,以及將來所有帶有release_date
ContentBuildDeviceGroupLink
對象。
我試圖像這樣使用Q object
:
in_future = Q(release_date__gte=timezone.now())
recent_past = Q(release_date__lt=timezone.now()).order_by('-release_date')[0]
ContentBuildDeviceGroupLink.objects
.filter(in_future & recent_past)
這不起作用並引發錯誤:
'datetime.datetime' object has no attribute 'order_by'
如何過濾與該對象release_date
在最近的過去,並與所有對象release_date
的未來?
我更改了方法,因此首先獲取最近的對象,然后過濾所有大於或等於該日期的對象。 但是,當只有1個ContentBuild
時,下面的queryset可以很好地工作,但是當有多個相關的ContentBuild
時,返回所有較舊的對象。
recent_past = ContentBuildDeviceGroupLink.objects
.filter(release_date__lte=timezone.now()).order_by('release_date').first()
ContentBuildDeviceGroupLink.objects.filter(release_date__gt=recent_past.release_date)
您不能將order_by
與查詢集一起使用。 嘗試這個。
in_future = Q(release_date__gte=timezone.now())
recent_past = Q(release_date__lt=timezone.now())
ContentBuildDeviceGroupLink.objects.filter(
in_future & recent_past
).order_by('-release_date').first()
您的第二次嘗試已經結束,但是有兩個問題:
first
對象,所以那個人的release_date
最早 ,而不是最新的 gt
而不是gte
似乎有點懷疑...我很驚訝當只有一個ContentBuild
時它拾取了任何東西 要在單個數據庫查詢中獲取它,您有兩個選項,具體取決於您的Django版本。 如果您使用的是django> = 2.0,則應該可以這樣做(我沒有一個項目,現在可以測試此項目):
from django.db.models import Max, Q, F
ContentBuildDeviceGroupLink.objects.annotate(
start_date=Max('release_date', filter=Q(release_date__lt=timezone.now())
).filter(release_date__gte=F('start_date'))
如果您使用的是django <2.0,請嘗試以下操作:
from django.db.models import Subquery, F
recent_dates = ContentBuildDeviceGroupLink.objects.filter(
release_date__lte=timezone.now()
).order_by('-release_date').values('release_date')
ContentBuildDeviceGroupLink.objects.annotate(
start_time=Subquery(recent_dates[:1])
).filter(release_date__gte=F('start_time'))
可能有一種更聰明的方法,但這似乎可行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.