Django - 加入两个模型

时间:2014-09-17 12:19:10

标签: django django-models

对于以下模型,我想检索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}}我的问题是如何在加入它们的同时从DeviceModelHistory同时检索数据,就像在设备ID上使用filter / select_related一样。 我宁愿不写自定义SQL查询。

1 个答案:

答案 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