Расширенный запрос Django к одной и той же модели
У меня есть Kit
и KitInOut
модели:
class Kit(models.Model):
name = models.CharField(max_length=255, blank=True, null=True)
class KitInOut(models.Model):
kit = models.ForeignKey(Kit, on_delete=models.CASCADE)
out = models.BoolField(default=True)
creation_timestamp = models.DateTimeField()
Я хочу выяснить, какие наборы вышли и не иметь тот же самый набор снова в результирующем запросе, который является чем-то вроде : "select * from KitInOut where, для каждого комплекта k
сохранить его в результате
- если погаснет** (
kit_went_out=1
) и - нет другого
KitInOut k2 where k2.kit=k and k2.creation_timestamp > k.creation_timestamp
"
Вот код, который у меня есть, который настолько неоптимизирован, что я не могу использовать его с более чем 500 KitInOut
строками:
k_in_out_s = KitInOut.objects.filter(out=True)
result = []
for obj in k_in_out_s:
if (KitInOut.objects.filter(
kit=obj.kit,
out=False,
creation_timestamp__gt=obj.creation_timestamp,
).count() == 0):
result.append(obj)
return result
Как это оптимизировать?
Думаю, вы можете попробовать следующим образом, используя Count
:
Kit.objects.annotate(
kit_out_counter=Count('kitinout', filter=Q(out=True,creation_timestamp__gt=F('creation_timestamp')),distinct=True),
kit_not_out_counter=Count('kitinout', filter=Q(out=False,creation_timestamp__gt=F('creation_timestamp')),distinct=True)
).filter(kit_out_counter__gt=0,kit_not_out_counter=0)
Здесь я подсчитываю экземпляры IN и OUT KitInOut для каждого объекта Kit в наборе запросов, а затем фильтрую на основе этого.