2014-09-17 7 views
3

Для следующих моделей я хочу, чтобы получить все устройства, которые имеют запись в таблице истории с 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 в указанном диапазоне. Функция фильтра выполняет INNER JOIN между DeviceModel и History на device id только для получения DeviceModel полей. Мой вопрос заключается в том, как я получаю данные одновременно из History и DeviceModel, присоединяя их как к фильтру/select_related на идентификаторе устройства. Я бы предпочел написать собственный SQL-запрос.

ответ

6

В своих моделях устройств и История модели связаны с внешним ключом от истории до 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 поля модели связаны по идентификатору для умолчанию, я говорю это потому, что ты делать:

device = models.ForeignKey(DeviceModel, to_field='id') 

, как вы можете видеть, что вы используете to_field='id', но это соотношение выполняется по умолчанию, если вы:

device = models.ForeignKey(DeviceModel) 

Вы получите те же результаты


(EDIT) Использование .values ​​() для получения списка [device.name, историю.дата]

Чтобы получить список, как вы сказали [device.name, history.date] вы можете использовать .values() функцию Джанго QuerySet, официальную документацию 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 
+0

Я хочу, чтобы сериализовать эти устройства + историю для каждого устройства и вернуть их как HttpResponse, когда я их сериализую, я получаю только устройства. – AlexandruC

+0

Добавить поле истории, которое вы хотите просмотреть в quer y, которое вы выполняете. – AlvaroAV

+0

Возможно, вы хотите отредактировать sql-запрос? – AlexandruC

Смежные вопросы