0

我有以下模型(简化):

class InscriptionDate(models.Model):
    start_date = models.ForeignKey('Date', related_name='+')
    end_date = models.ForeignKey('Date', related_name='+')
    dates_in_range = models.ManyToManyField('Date', blank=True)

class Date(models.Model):
    year = models.IntegerField(max_length=4)
    era = models.CharField(max_length=2, choices=ERA_CHOICES, default=BC)

在选择开始日期和结束日期之后,我希望在保存时为 dates_in_range 生成所有相关的 M2M 关系。这个想法是可以查询范围内的任何日期,并且它将返回与该日期关联的条目。

以下是不正确的,但这是我正在考虑采取的那种方法:

 def save(self):
       start = self.start_date.year
       end = self.end_date.year
       for i in range(start, end):
          self.dates_in_range.add(year)
       super(InscriptionDate, self).save()

是否可以以这种方式循环用于 M2M 关系的 add()?我可以通过这种方式从输入数据生成和添加整个 M2M 关系列表吗?

4

2 回答 2

0

为什么不?请记住在 /after/save()调用后执行此操作,因为您需要 PK 来添加 m2ms。

super(...).save()
self.dates_in_range.clear()
for year in range(start_year, end_year):
    date, created = Date.objects.get_or_create(year=year)
    self.dates_in_range.add(date)
于 2012-10-07T01:56:04.663 回答
0

您可以轻松使用已有的代码并使用保存后信号来实现它

例如

from django.dispatch import receiver

@receiver(models.signals.post_save, sender=InscriptionDate)
def add_dates_in_range(sender, instance, **kwargs):
    #assumes both years are in AD
    start_year = instance.start_date.year
    end_year = instance.end_date.year
    for year in range(start_year, end_year+1) #to include end_year
        date = Date.objects.get_or_create(year = year, era = 'AD')[0]
        instance.dates_in_range.add(date)

您也可以将 dates_in_range 实现为方法而不是多对多关系,但这实际上取决于您计划如何使用模型。

例如(假设您已经拥有 start_date 和 end_date 之间所有年份的 Date 对象,并且所有时代都是 AD)

class InscriptionDate(models.Model):
    start_date = models.ForeignKey('Date', related_name='+')
    end_date = models.ForeignKey('Date', related_name='+')
    def dates_in_range(self):
        return Date.objects.filter(year__lte = self.end_date.year, year__gte = self.start_date.year, era = 'AD')
于 2012-10-07T02:03:43.547 回答