对于以下模型,我想检索History表中具有条目的所有设备,其中transition_date在指定的时间间隔内:
class History(models.Model):
device = models.ForeignKey(DeviceModel, to_field='id')
transition_date = models.DateTimeField()
class Meta:
db_table = 'History'
class DeviceModel(models.Model):
id = models.IntegerField()
name = models.CharField()
class Meta:
db_table = 'Devices'
我有这段代码可以过滤指定的时间间隔:
devices = DeviceModel.objects.filter(history__transition_date__range=(startDate, endDate))
这给了我History
表与指定范围内的transition_date
一样多的行。
过滤器函数在DeviceModel
History
之间执行INNER JOIN,只检索device id
个字段。{1}}我的问题是如何在加入它们的同时从DeviceModel
和History
同时检索数据,就像在设备ID上使用filter / select_related一样。
我宁愿不写自定义SQL查询。
答案 0 :(得分:7)
在您的模型设备和历史模型与从History到DeviceModel的外键相关,这意味着当您拥有History对象时,您可以检索与设备模型相关的对它,反之亦然(如果你有一个设备,你可以得到它的历史)。
示例:
first_history = History.objects.all()[0]
first_history.device # This return the device object related with first_history
first_history.device.name # This return the name of the device related with first_history
但它也可以用另一种方式,你可以这样做:
first_device = Device.objects.all()[0]
first_device.history # This return the history object related with device
first_device.history.transition_date # Exactly as before, can access history fields
所以在您的查询中:
devices = DeviceModel.objects.filter(history__transition_date__range=(startDate, endDate))
返回设备列表,但您可以访问与每个设备对象相关的历史记录
对你来说还不够吗?您有一个设备列表,每个设备都可以访问其相关的历史记录对象
信息:当您声明 ForeignKey 字段时,模型会默认与ID相关联,我这样说是因为您这样做的:
device = models.ForeignKey(DeviceModel, to_field='id')
您可以看到您正在使用to_field='id'
,但如果您这样做,则此关系默认完成:
device = models.ForeignKey(DeviceModel)
您将获得相同的结果
(编辑)使用.values()获取列表[device.name,history.date]
要获得类似于您所说的[device.name, history.date]
的列表,您可以使用Django QuerySet的.values()
函数,官方文档here
您可以尝试以下内容:
devices = DeviceModel.objects.filter(history__transition_date__range=(startDate, endDate)).values('name','history__transition_date')
# Notice that it is 'history _ _ transition_date with 2 underscores