Django Create and Save Many instances of model when another object are created

后端 未结 1 836
自闭症患者
自闭症患者 2020-12-17 06:32

I am designing a game of chess and I would like to initialize the fields with chess figures (State model) after the start of a new ChessParty.
I read about

相关标签:
1条回答
  • 2020-12-17 07:08

    Using save():

    If you want to use the save() method, you could do the following:

    def save(self, *args, **kwargs):
        OtherModel.objects.create(something=kwargs['something'])
        YetAnotherModel.objects.create(
            something_else=kwargs['something_else']
        )
        super(ChessParty, self).save(*args, **kwargs)
    

    As @e4c5 states in his comment, it is easier to implement and that is why I include it!


    My take on the problem:

    Although you could do this on the save(), I would recommend instead to use a signal.

    Specifically use a post_save signal. Here is how to do this:

    1. Create a file your_app/signals.py:

      from django.db.models.signals import post_save
      from django.dispatch import receiver
      
      from your_app.models import ChessParty, OtherModel, YetAnotherModel
      
      
      @receiver(post_save, sender=ChessParty)
      def change_my_name_plz (sender, instance, created, **kwargs):
          if created:
              OtherModel.objects.create(something=kwargs['something'])
              YetAnotherModel.objects.create(
                  something_else=kwargs['something_else']
              )
      
    2. You now need to override the ready() function on your_app/app.py:

      from django.apps import AppConfig
      
      class YourAppConfig(AppConfig):
          name = 'your_project.your_app'
      
          def ready(self):
              import your_project.your_app.signals
      
    3. Finally, add the following in your_app/__init__.py:

      default_app_config = 'your_project.your_app.apps.YourAppConfig'
      

    Now you have a signal that will create an OtherModel and YetAnotherModel objects right after you create a new ChessParty object.


    Alternative way to define signals:

    There is an alternative way that does not use the @receiver decorator, but the connect() method:

    1. your_app/signals.py:

      from your_app.models import ChessParty, OtherModel, YetAnotherModel
      
      
      def change_my_name_plz (sender, instance, created, **kwargs):
          if created:
              OtherModel.objects.create(something=kwargs['something'])
              YetAnotherModel.objects.create(
                  something_else=kwargs['something_else']
              )
      
    2. your_app/app.py:

      from django.apps import AppConfig
      from django.db.models.signals import post_save
      
      from your_app.models import ChessParty
      from your_project.your_app.signals import change_my_name_plz
      
      class YourAppConfig(AppConfig):
          name = 'your_project.your_app'
      
          def ready(self):
              post_save.connect(change_my_name_plz, sender=ChessParty)
      
    3. your_app/__init__.py stays the same as above (step 3).


    0 讨论(0)
提交回复
热议问题