Проблема в том, что Vertex
объекты, которые вы загрузили с помощью prefetch_related
, не являются такими же объектами , как объекты в vertices
. Да, эти два объекта будут равны, проверка v1 == v2
будет успешной. Это потому, что Django проверяет, совпадают ли модели и первичные ключи, но не другое значение. Изменения, внесенные в один из объектов Vertex
, не будут отражены в другой модели.
Мы можем решить эту проблему, поддерживая словарь, который отображает pk
s в соответствующую вершину, например:
class PMap(models.Model):
# ...
def compute_flux(self, save=False):
vertices = self.vertex_set.order_by('-elevation')
<b>ver_dic = { v.pk: v for v in vertices }</b>
for vert in vertices:
vert.flux = 1.0 / len(vertices)
# Add flux from current to the downstream node.
for vert in vertices:
if vert.flow_sink_id != vert.pk:
<b>vertices[flow_sink_id]</b>.flux += vert.flux
Вы, вероятно, также забыли написать +=
вместо =
: последнее не будет иметь никакого эффекта, поскольку мы уже присвоили это значение вершине.
Таким образом, мы здесь кешируем Vertex
объекты в словаре, и вместо того, чтобы использовать результат предварительно выбранного значения, мы используем значение словаря.
Здесь мы предполагаем, что все вершины являются частью vertices
queryset, если это не так, мы все же можем позволить так работать, создав словарь, который «лениво» заполняется при поступлении новых элементов:
class PMap(models.Model):
# ...
def compute_flux(self, save=False):
vertices = self.vertex_set.order_by('-elevation').prefetch_related('flow_sink')
ver_dic = { v.pk: v for v in vertices }
# if some flow_sink vertices are not part of the PMap
for vert in vertices:
if vert.flow_sink_id not in ver_dic:
ver_dic[vert.flow_sink_id] = vert.flow_sink
for vert in vertices:
vert.flux = 1.0 / len(vertices)
# Add flux from current to the downstream node.
for vert in vertices:
if vert.flow_sink_id != vert.pk:
vertices[flow_sink_id].flux += vert.flux
Обратите внимание, что если вы не сохраните объект, однако, установка .flux
не будет иметь никакого эффекта, и если вы позже извлечете вершины снова, тогда эти вершины, конечно же, будут иметь старое значение.