Страницы

Поиск по вопросам

пятница, 27 декабря 2019 г.

Как произвести фильтрацию из дочерней таблицы с максимальной датой в Django?

#django


У меня есть 3 модели в проекте Django:

# Железо
class Hardware(models.Model):
    inventory_number = models.IntegerField(unique=True,)

# Подразделение
class Subdivision(models.Model):
    name = models.CharField(max_length=50,)

# Перемещения
class Relocation(models.Model):
    hardware = models.ForeignKey('Hardware',)
    subdivision = models.ForeignKey('Subdivision',)
    relocation_date = models.DateField(verbose_name='Дата перемещения', default=date.today())


Таблица 'Hardware_Relocation' со значениями для примера:

id hardware subdivision relocation_date

1 1 1   01.01.2009
2 1 2   01.01.2010
3 1 1   01.01.2011
4 1 3   01.01.2012
5 1 3   01.01.2013
6 1 3   01.01.2014
7 1 3   01.01.2015 # Сейчас железяка с id 1 хранится в подразделении 3 потому что
дата перемещения максимальная


Я бы хотел написать фильтр для поиска железа в конкретном подразделении на данный
момент. Т.е. нужно знать к примеру, какое железо находится в данном подразделении прямо
сейчас.

Я пытался написать фильтр:

subdivision = Subdivision.objects.get(pk=1)
hardware_list = Hardware.objects.annotate(relocation__relocation_date=Max('relocation__relocation_date')).filter(relocation__subdivision
= subdivision)


Сейчас hardware_list содержит hardware 1, но это не верно (потому что сейчас hardware
1 в подразделении 3).
hardware_list должен быть None в этом примере.

Следующий код тоже работает не верно (hardware_list содержит hardware 1, для подразделения 1).

limit_date = datetime.datetime.now()
q1 = Hardware.objects.filter(relocation__subdivision=subdivision,  relocation__relocation_date__lte=limit_date)
q2 = q1.exclude(~Q(relocation__relocation_date__gt=F('relocation__relocation_date')),
~Q(relocation__subdivision=subdivision))
hardware_list = q2.distinct()


Прошу помощи. Можно ли решить проблему без использования вьюх, только средствами Django?
    


Ответы

Ответ 1



subdivision = Subdivision.objects.get(pk=1) hardware_list = Hardware.objects.annotate( latest_relocation_date=Max('relocation__relocation_date') ).filter( relocation__relocation_date=F('latest_relocation_date'), relocation__subdivision=subdivision ) Подразумевается, что не будет несколько Relocation одного Hardware в один день. Иначе, если Relocation.id более позднего Relocation всегда больше более раннего Relocation, тогда: subdivision = Subdivision.objects.get(pk=1) hardware_list = Hardware.objects.annotate( latest_relocation_date=Max('relocation__relocation_date') ).filter( relocation__relocation_date=F('latest_relocation_date'), ).annotate( latest_relocation_id=Max('relocation__id') ).filter( relocation__id=F('latest_relocation_id'), relocation__subdivision=subdivision ) Правда, в этом случае можно обойтись без relocation_date: subdivision = Subdivision.objects.get(pk=1) hardware_list = Hardware.objects.annotate( latest_relocation_id=Max('relocation__id') ).filter( relocation__id=F('latest_relocation_id'), relocation__subdivision=subdivision )

Комментариев нет:

Отправить комментарий