Django model instance foreign keys lose consistency during state changes

I have a model,, Matchwith two foreign keys:

class Match(model.Model):
   winner = models.ForeignKey(Player)
   loser = models.ForeignKey(Player)

When I go through Match, I find that each instance of the model uses a unique object for the foreign key. It ends by biting me because it introduces inconsistency, here is an example:

>>> 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
>>>

I solved this problem as follows:

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

My question is: is there a better way to solve the problem with QuerySets without requiring a call at any time? If not, I would like to make the solution more universal: how can you get a list of foreign keys of a model instance or do you have a better general solution to my problem?

Please correct me if you think that I do not understand why this is happening.

+3
4

, , , , , .

, select_related() , . :

match = Match.objects.filter(...).get()

:

match = Match.objects.select_related().filter(...).get()

. - ( ).

: . . , , , , ...

+2

, django-idmapper SharedMemoryModel, .

+1

get_or_create() Player? , , , ( ) . / .

0

Source: https://habr.com/ru/post/1749514/


All Articles