Django обновляет объекты m2m при сохранении
У меня есть rel m-2-m и я хочу обновить rel B после добавления любого rel A через страницу администратора.
Вот подробности:
У меня есть 2 модели, Матч (rel A) и Игрок (rel B). Я хочу обновлять Player.matches_played каждый раз, когда добавляется новый матч с этим игроком в Match.team1 или Match.team2.
Как я могу этого добиться???
модели
class Match(models.Model):
    data=models.DateField(auto_now_add=False,auto_now=False)
    team1=models.ManyToManyField('players.Player',related_name='team_1')
    team2=models.ManyToManyField('players.Player',related_name='team_2')
    score_team1=models.IntegerField(validators=[MinValueValidator(0)])
    score_team2=models.IntegerField(validators=[MinValueValidator(0)])
class Player(models.Model):
    matches_played= models.IntegerField(validators=[MinValueValidator(0)], default=0)
Я пробовал сигналы, но в post_save сигнал {instance.team1} или instance.team1.all() возвращают пустой QuerySet, что я считаю правильным, так как M2M rel сохраняется позже. Затем я попробовал m2m_changed, но этот сигнал не срабатывает при сохранении через страницу администратора. Что я упускаю?
@receiver(post_save, sender=Match, dispatch_uid="update_player_game_count")
def update_player_games(sender, instance, created, **kwargs):
    print(f'created {instance.pk}')
    print(f'created {instance.team1}')
    print(f'created {instance.team2}')
    print(f'created {instance.score_team1}')
    print(instance.team1.all())
@receiver(m2m_changed, sender=Match, dispatch_uid="update_player_game_count")
def update_player_game(sender, instance, created, action, **kwargs):
    print(action)
    if action == 'post_add':
        print(action)
Большое спасибо за помощь
альтернатива, о которой я думал, это получать данные через свойство в Player, например, так, но я думаю, с точки зрения производительности, лучше обновлять строки каждый раз, когда добавляется матч, а затем считать матчи каждый раз, когда запрашивается игрок
Пример
@property
def matches_played(self):
    return Match.objects.filter(team1__nome=self.nome).count()+Match.objects.filter(team2__nome=self.nome).count()
 Отправителем сигнала m2m_change [Django-doc] является не Match, а Match.team1.through, и/или Match.team2.through, поэтому:
@receiver(
    m2m_changed,
    sender=Match.team1.through,
    dispatch_uid='update_player_game_count1',
)
@receiver(
    m2m_changed,
    sender=Match.team2.through,
    dispatch_uid='update_player_game_count2',
)
def update_player_game(sender, instance, created, action, **kwargs):
    print(action)
    if action == 'post_add':
        print(action)При этом хранить количество сыгранных матчей в качестве поля в модели не имеет особого смысла. Мы можем определить его при необходимости с помощью:
from django.db.models import Count
Player.objects.annotate(
    total_matches=Count('team1', distinct=True) + Count('team2', distinct=True)
)Furthermore I don't think using two ManyToManyFields is per se the best modeling here. You might want to use a single ManyToManyField with a through=… model [Django-doc] that determines if the player played for the first or second team.