Изменение объекта QuerySet на лету в Django - PullRequest
5 голосов
/ 15 марта 2012

Могу ли я сделать это в виде?

a = SomeTable.objects.all()
for r in a:
    if r.some_column == 'foo':
        r.some_column = 'bar'

Это работало как чемпион, но я пробовал нечто подобное где-то еще, и я получал странные результаты, подразумевая, что объекты QuerySet не любят шутить. И я не видел в документах ничего хорошего или плохого для такого рода уловок.

Я знаю, что есть и другие способы сделать это, но я специально хочу знать, если это плохая идея, почему она плохая, и если она действительно плохая, то какой «лучший» самый django / pythonic способ изменить значения на лету будет.

Ответы [ 2 ]

6 голосов
/ 15 марта 2012

Это нормально, если позже вы не сделаете ничего, что приведет к переоценке набора запросов - например, его нарезке.Это сделает еще один запрос к базе данных, и все ваши измененные объекты будут заменены свежими.

Чтобы защитить себя от этого, сначала нужно преобразовать в список:

a = list(SomeTable.objects.all())

Таким образом, дальнейшая нарезка и т. Д. Не вызовет новый вызов БД, и любые изменения будут сохранены.

0 голосов
/ 15 марта 2012

Да. Смотрите документы здесь

SomeTable.objects.filter(some_column='foo').update(some_column='bar')

Я бы пошел с идиомой Джанго. Он выполняет SQL с помощью одного оператора с «где» и «обновлением», а отправляет несколько операторов SQL, как это сделал бы ваш код. Это экономит время. Проверьте с помощью 'connection' Django для проверки времени SQL.

...