Django中基于单个模型创建多实例?信号实现问题求助
Django模型实例批量创建问题修复
我正尝试在Django中创建模型实例时生成多个实例,最终目标是创建多个实例,但目前先想让信号正常工作。我写的代码无法运行,想要实现创建该模型的副本,原代码如下:
from datetime import datetime, timedelta import django from django.conf import settings from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver class BudgetTransaction(models.Model): """ Individual transaction for Budget """ transaction_types = [ ('FI', 'Fixed Income'), ('FE', 'Fixed Expenses'), ('EC', 'Extra Cashflow'), ] frequencies = [ ('one', 'one off'), ('wk', 'weekly'), ('fort', 'fortnightly'), ('mon', 'monthly'), ('yr', 'yearly'), ('day', 'specific day'), ] today = datetime.today().strftime('%Y-%m-%d') owner = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, help_text="Owner of the item" ) transaction_type = models.CharField(max_length=40, choices=transaction_types, default=1) transaction_name = models.CharField(max_length=100, null=False) transaction_amount = models.IntegerField(null=False) next_date = models.DateField(null=False, default=today) frequency = models.CharField(max_length=20, choices=frequencies, default=1) complete = models.BooleanField(default=False) def __str__(self): return self.transaction_name class Meta: ordering = ['next_date'] @receiver(post_save, sender=BudgetTransaction) def create_forecasted(sender, instance, created, **kwargs): if created: today = datetime.today() this_month = today.month months_left = 12 - this_month if sender.frequency == "mon": BudgetTransaction.objects.create(owner=instance.owner)
核心问题及修复方案
信号中错误引用sender而非实例
sender是模型类本身,不是创建的具体实例,判断频率应该用instance.frequency而非sender.frequency。创建副本时缺少必填字段
create方法仅传入owner,但模型中transaction_name、transaction_amount等都是非空字段,需要复制原实例的对应值。默认值静态化问题
类级变量today只会在Django启动时计算一次,不会动态更新当前日期,改用lambda函数动态生成默认日期。choices默认值不匹配
transaction_type和frequency的默认值设为1,但choices选项是字符串类型,需对应选项的键值(如'FE'、'one')。
修复后的完整代码
from datetime import datetime, timedelta from django.conf import settings from django.db import models from django.db.models.signals import post_save from django.dispatch import receiver class BudgetTransaction(models.Model): """ 预算的单个交易记录 """ transaction_types = [ ('FI', '固定收入'), ('FE', '固定支出'), ('EC', '额外现金流'), ] frequencies = [ ('one', '一次性'), ('wk', '每周'), ('fort', '每两周'), ('mon', '每月'), ('yr', '每年'), ('day', '特定日期'), ] owner = models.ForeignKey( settings.AUTH_USER_MODEL, on_delete=models.CASCADE, help_text="记录所有者" ) transaction_type = models.CharField(max_length=40, choices=transaction_types, default='FE') transaction_name = models.CharField(max_length=100, null=False) transaction_amount = models.IntegerField(null=False) # 动态获取当前日期,避免启动时固定值 next_date = models.DateField(null=False, default=lambda: datetime.today().date()) frequency = models.CharField(max_length=20, choices=frequencies, default='one') complete = models.BooleanField(default=False) def __str__(self): return self.transaction_name class Meta: ordering = ['next_date'] @receiver(post_save, sender=BudgetTransaction) def create_forecasted(sender, instance, created, **kwargs): if created and instance.frequency == "mon": # 生成后续11个月的月度交易实例 for month_offset in range(1, 12): # 计算对应月份的日期(可根据实际需求调整日期计算逻辑) next_transaction_date = instance.next_date + timedelta(days=30 * month_offset) # 复制原实例字段,创建新实例 BudgetTransaction.objects.create( owner=instance.owner, transaction_type=instance.transaction_type, transaction_name=instance.transaction_name, transaction_amount=instance.transaction_amount, next_date=next_transaction_date, frequency=instance.frequency, complete=instance.complete )
内容的提问来源于stack exchange,提问作者MitchW
相关产品推荐
相关产品推荐

