我手上有一个难题。作为练习,我试图写一个查询集,帮助我想象我应该优先与哪些专业联系人通信。
class Person(models.Model):
name = models.CharField(max_length=256)
email = models.EmailField(blank=True, null=True)
target_contact_interval = models.IntegerField(default=45)
class ContactInstance(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE, related_name='contacts')
date = models.DateField()
notes = models.TextField(blank=True, null=True)
target_contact_interval
上
Person
模型通常指定在我再次接触此人之前应经过的最长天数。
A.
ContactInstance
反映与某个对象的单点接触
人
. A.
可能与许多人有相反的关系
ContactInstance
物体。
那么,第一个呢
在queryset中,应该拥有
date
最近的
ContactInstance
所以我的梦函数看起来像:
Person.objects.order_by(contact__latest__date__day - timedelta(days=F(target_contact_interval))
但当然,由于各种原因,这是行不通的。
我相信有人可以为此编写一些原始的PostgreSQL,但我真的很想知道是否有一种方法可以仅使用Django ORM来完成它。
这是我到目前为止找到的碎片,但我在把它们拼在一起时遇到了困难。
我也许可以用一个
Subquery
from django.db.models import OuterRef, Subquery
latest = ContactInstance.objects.filter(person=OuterRef('pk')).order_by('-date')
Person.objects.annotate(latest_contact_date=Subquery(latest.values('date')[:1]))
null values at the end
:
from django.db.models import F
Person.objects.order_by(F('last_contacted').desc(nulls_last=True))
但我不知道接下来该怎么办。我一直在努力把所有的东西都放进去
order_by()
F()
timedelta
就我而言。
更新:
我改变了主意
模仿
DurationField
正如建议的那样。以下是我尝试使用的查询:
ci = ContactInstance.objects.filter(
person=OuterRef('pk')
).order_by('-date')
Person.objects.annotate(
latest_contact_date=Subquery(ci.values('date'[:1])
).order_by((
(datetime.today().date() - F('latest_contact_date')) -
F('target_contact_interval')
).desc(nulls_last=True))
在我看来,这应该是可行的,但是queryset仍然没有正确排序。