Подписка QuerySet не будет работать должным образом - PullRequest
0 голосов
/ 04 апреля 2011

когда получен QuerySet с использованием фильтра, и для выполнения операции изменения и сохранения легко использовать следующий код:

qs = SomeModel.objects.filter(owner_id=123)
# suppose qs has 1 or many elements
last_login_time = qs[0].last_login_time
qs[0].last_login_time = datetime.now()    # I expect it can assign the new value, but it won't
assertEquals(qs[0].last_login_time, last_login_time)   # YES, it doesn't change
qs[0].save()   #So it won't update the old record

И после выяснения этого будет использоваться следующий код, и онworks:

qs = SomeModel.objects.filter(owner_id=123)
# suppose qs has 1 or many elements
obj = qs[0]
last_login_time = obj.last_login_time
obj.last_login_time = datetime.now()    # I expect it can assign the new value, but it will
assertNotEquals(obj.last_login_time, last_login_time)   # YES, it does change
obj.save()   #So it will update the old record as expected

И я встречал, что некоторые из моих друзей / коллег используют первый подход для обновления записи.И ИМО, это естественно и склонно к использованию.(когда вы набираете qs [0] и набираете obj , они имеют одинаковый тип)

После прочтения кода (db.models.query) он можетвыяснить почему. (когда вы подпишете QuerySet, он будет использовать qs = self._clone (), и присвоение значения не изменится вообще)

Возможные решения:

  1. сделайте назначение работы для подписчика QuerySet
  2. объявите, что первый подход неверен, и пусть пользователи знают это

Поэтому я хочу спросить:

  1. Является ли мой вопрос реальной проблемой для django? (Мне интересно, почему разработчик django не заставляет его работать должным образом)
  2. Что вы предлагаете по этому поводу?И как вы предпочитаете такую ​​проблему?

Ответы [ 2 ]

0 голосов
/ 04 апреля 2011

Я не совсем уверен, что вы спрашиваете здесь.Вы говорите, что это ошибка?Я так не думаю, это четко определенное поведение: набор запросов ленив, но оценивается, когда вы итерируете или разбиваете его на части.Каждый раз, когда вы нарезаете его, вы получаете новый объект.Это логическое следствие того факта, что секционирование само по себе не приводит к оценке нерезаного набора запросов - если результат еще не кэширован, секционирование будет выполнять один вызов базы данных с LIMIT 1, чтобы получить только одинрезультат.В противном случае у вас останутся крайне нежелательные побочные эффекты.

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

0 голосов
/ 04 апреля 2011

Используйте update для обновления полей в наборе запросов.

...