Python 如何通过单独模型中最新对应条目中的文本字段过滤Django查询集

Python 如何通过单独模型中最新对应条目中的文本字段过滤Django查询集,python,django,django-models,Python,Django,Django Models,我有一个模型,其中我需要几个特定字段的历史数据,所以我将这些字段放在一个单独的模型中,并具有外键关系 有点像这样: class DataThing(models.Model): # a bunch of fields here... class DataThingHistory(models.Model): datathing_id = models.ForeignKey('DataThing', on_delete=models.CASCADE) text_with

我有一个模型,其中我需要几个特定字段的历史数据,所以我将这些字段放在一个单独的模型中,并具有外键关系

有点像这样:

class DataThing(models.Model):
    # a bunch of fields here...


class DataThingHistory(models.Model):
    datathing_id = models.ForeignKey('DataThing', on_delete=models.CASCADE)
    text_with_history = models.CharField(max_length=500, null=True, blank=True)
    # other similar fields...
    timestamp = models.DateTimeField()
现在,我正在尝试使用后者中最新对应条目中的文本字段过滤前一个模型

基本上,如果这些不是单独的模型,我会尝试以下方法:

search_results = DataThing.objects.filter(text_with_history__icontains=searchterm)
但我还没有找到一个好方法来跨越一对多关系,在后一个模型中只使用具有最新时间戳的条目,至少通过使用Django ORM


我知道如何使用原始SQL进行查询,但如果可能的话,我真的希望避免使用原始SQL。

您可以通过查询
DataThing
同时参考
DataThingHistory

search_results = DataThing.objects.filter(datathinghistory__text_with_history__icontains=searchterm)
检查上的django文档

编辑:

我先前的回答不完整。为了搜索每个
DataThing
的最新历史记录,您需要使用
Max
在时间戳上添加
注释:

from django.db.models import Max

search_results = search_results.values('field1', 'field2',...).annotate(latest_history=Max('datathinghistory__timestemp'))

这不会为您提供完整的
DataThing
对象,但您可以根据需要向
值添加任意多的字段。

此解决方案利用了当前只有Postgres支持的字段:

latest_things = DataThingHistory.objects.
    order_by('datathing_id_id', '-timestamp').
    distinct('datathing_id_id')

lt_with_searchterm = DataThingHistory.objects.
    filter(id__in=latest_things, text_with_history__icontains=searchterm)

search_results = DataThing.objects.filter(datathinghistory__in=lt_with_searchterm)

这将导致单个数据库查询。为了可读性,我已经拆分了查询,但是您可以将其嵌套到单个语句中。顺便说一句,正如您在这里看到的,
foo_id
对于
ForeignKey
字段来说不是一个好名字。

我如何只检查带有最新
时间戳的
DataThingHistory
对象?似乎只需执行您描述的查询即可搜索所有相关的
DataThingHistory
条目。很抱歉,我完全错过了您的要求。我编辑了我的答案,看看是否有意义。谢谢你,我刚刚尝试了这个,它确实产生了一个查询。我必须做一些测试,看看它在实践中运行得如何,但这似乎解决了我目前的问题。