'Create several instances out of a related model in Django

In university as a part of a project we have to develop a liga system with Django. I have my basic app running and also my models are already set up.

from django.db import models
from datetime import datetime

# Create your models here.
class Player(models.Model):
    vorname         = models.CharField(max_length=30)
    nachname        = models.CharField(max_length=50)
    created_on      = models.DateTimeField(auto_now_add=True)
    email           = models.EmailField()


class Liga(models.Model):
    name            = models.CharField(max_length=50)
    participants    = models.ManyToManyField(Player)
    created_on      = models.DateTimeField(auto_now_add=True)
    is_active       = models.BooleanField(default=False)
    is_completed    = models.BooleanField(default=False)

class Game(models.Model):
    liga            = models.ForeignKey(Liga, on_delete='DO NOTHING')
    player1         = models.CharField(max_length=100)
    player2         = models.CharField(max_length=100)
    score_pl1       = models.IntegerField(blank=True)
    score_pl2       = models.IntegerField(blank=True)
    is_completed    = models.BooleanField(default=False)
    completed_on    = models.DateTimeField(auto_now_add=True)

Now when I've created a new liga in the admin area I want Django to automatically create the Game instances (which could be several). I've tried several different ways to do that but couldn't fix that problem. When I create a Liga instance I want the method below to be called. The method creates all games of a certain amount of players. Each game shall be stored in the database by using the Game Model.

player = ['Max', 'Sebastian', 'Tim', 'Bernd', 'Klaas', 'Kyle', 'Andreas', 'Jürgen']

def create_games(players):
    
    n = len(players)
    for i in range(0,n):
        print('--------------------------')
        print('Gameday ' + str(i+1))
        print('--------------------------')
        
        if i == len(players)-1:
            game = [players[i], players[0]]
        else:
            game = [players[i], players[n-1]]
        print(game)
        for k in range(1, n//2):
            game = [players[(i+k) % (n-1)], players[(i-k)%(n-1)]]
            print(game)
        print(' ')
        


liga1 = create_games(player)

Example output of create_games:

--------------------------
Gameday 1
--------------------------
['Max', 'Jürgen']
['Sebastian', 'Andreas']
['Tim', 'Kyle']
['Bernd', 'Klaas']
 
--------------------------
Gameday 2
--------------------------
['Sebastian', 'Jürgen']
['Tim', 'Max']
['Bernd', 'Andreas']
['Klaas', 'Kyle']
 
--------------------------
Gameday 3
--------------------------
['Tim', 'Jürgen']
['Bernd', 'Sebastian']
['Klaas', 'Max']
['Kyle', 'Andreas']
 
--------------------------
Gameday 4
--------------------------
['Bernd', 'Jürgen']
['Klaas', 'Tim']
['Kyle', 'Sebastian']
['Andreas', 'Max']
 
--------------------------
Gameday 5
--------------------------
['Klaas', 'Jürgen']
['Kyle', 'Bernd']
['Andreas', 'Tim']
['Max', 'Sebastian']
 
--------------------------
Gameday 6
--------------------------
['Kyle', 'Jürgen']
['Andreas', 'Klaas']
['Max', 'Bernd']
['Sebastian', 'Tim']
 
--------------------------
Gameday 7
--------------------------
['Andreas', 'Jürgen']
['Max', 'Kyle']
['Sebastian', 'Klaas']
['Tim', 'Bernd']
 
--------------------------
Gameday 8
--------------------------
['Jürgen', 'Max']
['Sebastian', 'Andreas']
['Tim', 'Kyle']
['Bernd', 'Klaas']
 


Solution 1:[1]

You could call this function after a liga got crated using post_save signal(https://docs.djangoproject.com/en/2.2/ref/signals/#post-save):

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=Liga)
def my_callback(sender, **kwargs):
    the_liga_created = kwargs.get('instance')
    print("Do whatever you want here; like calling create_games")

It is common to put such code after model definition in models.py or in the app_config ready function, often a file called signals.py just gets imported in ready function to connect signals as a side effect of the import...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1