Другой протест состоит в том, что многие люди путают финал, чтобы означать, что содержание переменной экземпляра не может измениться, а не что ссылка не может измениться.
Похоже, ваш набор данных будет достаточно большим, чтобы вы могли немного денормализовать вещи. Вы пробовали отслеживать последний объект Valor в объекте Robot?
class Robot(models.Model):
# ...
last_valor = models.ForeignKey('Valor', null=True, blank=True)
А затем используйте сигнал post_save , чтобы выполнить обновление.
from django.db.models.signals import post_save
def record_last_valor(sender, **kwargs):
if kwargs.get('created', False):
instance = kwargs.get('instance')
instance.robot.last_valor = instance
post_save.connect(record_last_valor, sender=Valor)
Вы заплатите стоимость дополнительной транзакции db при создании объектов Valor, но поиск last_valor будет быстрым. Поиграйте с этим и посмотрите, стоит ли оно того для вашего приложения.
Есть ли лимитное предложение в django? Таким образом, вы можете получить базу данных, просто вернув одну запись.
mysql
select * from table where x = y limit 1
sql server
select top 1 * from table where x = y
oracle
select * from table where x = y and rownum = 1
Я понимаю, что это не переведено на django, но кто-то может вернуться и очистить это.
Если ни одно из предыдущих предложений не работает, я бы предложил исключить Django из уравнения и запустить этот необработанный sql для вашей базы данных. Я предполагаю имена ваших таблиц, поэтому вам, возможно, придется внести соответствующие изменения:
SELECT * FROM valor v WHERE v.robot_id = [robot_id] ORDER BY id DESC LIMIT 1;
Это медленно? Если да, пусть ваша СУБД (MySQL?) Объяснит вам план запроса. Это скажет вам, выполняет ли он полное сканирование таблицы, что вам, очевидно, не нужно с такой большой таблицей. Вы также можете отредактировать свой вопрос и включить схему для таблицы valor
, чтобы мы могли ее увидеть.
Кроме того, вы можете увидеть SQL, который Django генерирует, выполнив это (используя набор запросов, предоставленный Питером Rowell):
qs = Valor.objects.filter(robot=r).order_by('-id')[0]
print qs.query
Убедитесь, что SQL похож на "необработанный" запрос, который я опубликовал выше. Вы также можете заставить свою СУБД объяснить вам этот план запроса.
Ну, здесь нет предложения order_by, поэтому мне интересно, что вы имеете в виду под словом «последний». Предполагая, что вы имели в виду «последний добавленный»,
Valor.objects.filter(robot=r).order_by('-id')[0]
может сработать за вас.