У меня есть модель, Match
, с двумя внешними ключами:
class Match(model.Model):
winner = models.ForeignKey(Player)
loser = models.ForeignKey(Player)
Когда я повторяю цикл Match
, я обнаруживаю, что каждый экземпляр модели использует уникальный объект для внешнего ключа. Это в конечном итоге кусает меня, потому что это вводит несогласованность, вот пример:
>>> def print_elo(match_list):
... for match in match_list:
... print match.winner.id, match.winner.elo
... print match.loser.id, match.loser.elo
...
>>> print_elo(teacher_match_list)
4 1192.0000000000
2 1192.0000000000
5 1208.0000000000
2 1192.0000000000
5 1208.0000000000
4 1192.0000000000
>>> teacher_match_list[0].winner.elo = 3000
>>> print_elo(teacher_match_list)
4 3000 # Object 4
2 1192.0000000000
5 1208.0000000000
2 1192.0000000000
5 1208.0000000000
4 1192.0000000000 # Object 4
>>>
Я решил эту проблему так:
def unify_refrences(match_list):
"""Makes each unique refrence to a model instance non-unique.
In cases where multiple model instances are being used django creates a new
object for each model instance, even if it that means creating the same
instance twice. If one of these objects has its state changed any other
object refrencing the same model instance will not be updated. This method
ensure that state changes are seen. It makes sure that variables which hold
objects pointing to the same model all hold the same object.
Visually this means that a list of [var1, var2] whose internals look like so:
var1 --> object1 --> model1
var2 --> object2 --> model1
Will result in the internals being changed so that:
var1 --> object1 --> model1
var2 ------^
"""
match_dict = {}
for match in match_list:
try:
match.winner = match_dict[match.winner.id]
except KeyError:
match_dict[match.winner.id] = match.winner
try:
match.loser = match_dict[match.loser.id]
except KeyError:
match_dict[match.loser.id] = match.loser
Мой вопрос: есть ли способ решить проблему более элегантно с помощью QuerySets без необходимости вызывать функцию сохранения в любой момент? Если нет, я бы хотел сделать решение более общим: как вы можете получить список внешних ключей для экземпляра модели или у вас есть лучшее общее решение для моей проблемы?
Пожалуйста, поправьте меня, если вы думаете, что я не понимаю, почему это происходит.