Django在创建另一个对象时创建并保存许多模型实例 [英] Django Create and Save Many instances of model when another object are created

查看:78
本文介绍了Django在创建另一个对象时创建并保存许多模型实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在设计一个国际象棋游戏,我想在新的 ChessParty 开始后用象棋人物(状态模型)初始化字段。

我读到有关重写 save()模型方法的信息,但是我不知道如何在我的情况下使用它。

我正在阅读有关 post_save 之类的信号,但是我有同样的问题。

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 overriding the save() model method, but I don't know how to use it in my case.
I am reading about signals like post_save, but I have the same problem.

    def save(self, *args, **kwargs):
        (Here i want create many instances of another Model)
    super(ChessParty, self).save(*args, **kwargs)

这是到目前为止的代码:

And here is my code so far:

class ChessParty(models.Model):
    chessparty_id = models.AutoField("ID partii", primary_key=True)
    arbiter = models.ForeignKey(Arbiter, related_name='sedzia', 
    verbose_name="Sędzia")
    white = models.ForeignKey(Player, related_name='Białe', 
    verbose_name="Białe figury")
    black = models.ForeignKey(Player, related_name='Czarne', 
    verbose_name="Czarne figury")
    tournament = models.ForeignKey(Tournament, verbose_name="Nazwa turnieju")

    def __str__(self):
        return "{white} vs {black}, ({tournament})"\
            .format(black=self.black, white=self.white, tournament=self.tournament)


class OneMove(models.Model):
party = models.ForeignKey(ChessParty, default='0', verbose_name="Partia")
chessman = (
    ('a1_w_rook', 'biała wieża a1'), ('h1_w_rook', 'biała wieża h1'),
    ('b1_w_knight', 'biały skoczek b1'), ('g1_w_knight', 'biały skoczek g1'),
    ('c1_w_bishop', 'biały goniec c1'), ('f1_w_bishop', 'biały goniec f1'),
    ('d1_w_queen', 'biały hetman d1'), ('e1_w_king', 'biały król e1'),
    ('a2_w_pawn', 'biały pion a2'), ('b2_w_pawn', 'biały pion b2'),
    ('c2_w_pawn', 'biały pion c2'), ('d2_w_pawn', 'biały pion d2'),
    ('e2_w_pawn', 'biały pion e2'), ('f2_w_pawn', 'biały pion f2'),
    ('g2_w_pawn', 'biały pion g2'), ('h2_w_pawn', 'biały pion h2'),
    ('a8_b_rook', 'czarna wieża a1'), ('h8_b_rook', 'czarna wieża h8'),
    ('b8_b_knight', 'czarny skoczek b1'), ('g8_b_knight', 'czarny skoczek g8'),
    ('c8_b_knight', 'czarny goniec c1'), ('f8_b_bishop', 'czarny goniec f8'),
    ('d8_b_queen', 'czarny hetman d1'), ('e8_b_king', 'czarny król e8'),
    ('a7_b_pawn', 'czarny pion a7'), ('b7_b_pawn', 'czarny pion b7'),
    ('c7_b_pawn', 'czarny pion c7'), ('d7_b_pawn', 'czarny pion d7'),
    ('e7_b_pawn', 'czarny pion e7'), ('f7_b_pawn', 'czarny pion f7'),
    ('g7_b_pawn', 'czarny pion g7'), ('h7_b_pawn', 'czarny pion h7'),
 )
chessman = models.CharField(max_length=30, choices=chessman, default='pionek', verbose_name="Figura Szachowa")
mymove = []
for a, b in itertools.product('abcdefgh', '12345678'):
    name = a + b
    mymove.append((name, name))
mytuple = tuple(mymove)
move = models.CharField(max_length=2, choices=mytuple, default='a1', verbose_name="Ruch na")

class Meta:
    abstract = True


class State(OneMove):
state_id = models.PositiveIntegerField(default=0, verbose_name="numer ruchu")
is_capture = models.BooleanField(default=False, verbose_name="Czy zbita")
capture_choice = (
    ('true', 'zbity'),
    ('false', 'nie zbity'),
)
is_capture = models.CharField(max_length=9, choices=capture_choice, default='false', verbose_name="Czy zbity")


推荐答案

使用 save()

Using save():

如果要使用 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)

如@ e4c5在他的声明中所述评论,它更易于实现,这就是为什么要包含它!

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

我对这个问题的看法:

尽管您可以在 save()上执行此操作,但我还是建议使用信号

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

具体使用 post_save 信号。操作方法如下:

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


  1. 创建文件 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']
        )


  • 您现在需要覆盖<$ c $在 your_app / app.py 上的c> ready()函数:

  • 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
    


  • 最后,在 your_app / __ init __。py 中添加以下内容:

    default_app_config = 'your_project.your_app.apps.YourAppConfig'
    


  • 现在,您将创建一个创建 OtherModel 的信号在您创建新的 ChessParty 对象之后,即可查看YetAnotherModel 对象。

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

    定义信号的另一种方法:

    还有一种不使用 @receiver 装饰器,但 connect() 方法:

    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']
            )
    


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


  • your_app / __ init __。py 保持与上述相同(步骤3)。

  • your_app/__init__.py stays the same as above (step 3).

    这篇关于Django在创建另一个对象时创建并保存许多模型实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆