You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django中创建CardsDesk模型时自动生成78个Card对象的实现方案

实现思路与代码示例

1. 完善Card模型关联

首先给Card模型添加外键关联CardsDesk,确保每张卡牌归属对应牌组;同时将分散的卡牌选项合并为一个完整可遍历的列表,方便批量生成。

修改后的Card模型:

class Card(models.Model):
    # 关联所属牌组
    desk = models.ForeignKey(CardsDesk, on_delete=models.CASCADE, related_name='cards')
    # 原始分组选项
    CHOICES = [
        ('Мечи', (
                ('Swords_1', 'Туз мечей'),
                ('Swords_2', 'Двойка мечей'),
                # ... 其他剑类卡牌
            )
        ),
    ]
    CARDS_TYPE = [
        ('Diamonds', 
            ('Diamonds_1', 'Diamonds_1'),
            ('Diamonds_2', 'Diamonds_2'),
            # ... 其他花色卡牌
        ),
    ]
    # 合并所有卡牌选项为扁平列表
    ALL_CARD_CHOICES = []
    for _, sub_choices in CHOICES:
        ALL_CARD_CHOICES.extend(sub_choices)
    for _, sub_choices in CARDS_TYPE:
        ALL_CARD_CHOICES.extend(sub_choices)
    # 卡牌类型字段
    card_type = models.CharField(max_length=255, choices=ALL_CARD_CHOICES)
    # 卡牌名称(可自动从选项中获取)
    name = models.CharField(max_length=255, blank=True)

    def save(self, *args, **kwargs):
        if not self.name:
            self.name = dict(self.ALL_CARD_CHOICES).get(self.card_type)
        super().save(*args, **kwargs)

2. 重写CardsDesk的save方法自动生成卡牌

在CardsDesk的save方法中判断是否为新创建实例(无pk值),若是则批量生成78张卡牌:

class CardsDesk(models.Model):
    name = models.CharField(max_length=255, verbose_name='Название колоды', blank=True, null=True)
    image = models.ImageField(upload_to='media/', verbose_name='Картинка колоды')

    def save(self, *args, **kwargs):
        is_new = self.pk is None
        # 先保存牌组实例
        super().save(*args, **kwargs)
        # 新创建时批量生成卡牌
        if is_new:
            card_objects = []
            for card_code, card_name in Card.ALL_CARD_CHOICES:
                card_objects.append(
                    Card(
                        desk=self,
                        card_type=card_code,
                        name=card_name
                    )
                )
            # 批量插入效率远高于循环单条保存
            Card.objects.bulk_create(card_objects)

3. 替代方案:使用Django post_save信号

若不想修改save方法,可通过信号触发卡牌生成:

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

@receiver(post_save, sender=CardsDesk)
def create_cards_for_desk(sender, instance, created, **kwargs):
    if created:
        card_objects = []
        for card_code, card_name in Card.ALL_CARD_CHOICES:
            card_objects.append(
                Card(
                    desk=instance,
                    card_type=card_code,
                    name=card_name
                )
            )
        Card.objects.bulk_create(card_objects)

注意:使用信号需确保代码在Django启动时被加载,可放在models.py或在apps.py的ready方法中导入。

关键注意事项

  • 检查ALL_CARD_CHOICES的总长度是否为78,避免卡牌数量不符
  • 优先使用bulk_create提升批量创建效率
  • 若卡牌需初始化其他字段,可在批量创建时直接赋值

内容的提问来源于stack exchange,提问作者skyhelper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 11:40:14