В модели создаются дни для каждого созданного года

Я новичок в Django (и Python) и у меня проблема с инициализацией моей модели. Для каждого учебного года, созданного в базе данных, я хочу, чтобы соответствующие дни (не точно 365/366, а > 300) были созданы с value по умолчанию 0 (отношение "один-ко-многим"). Я узнал, что пытаться сделать это нужно не в конструкторе, а после того, как конструктор выполнится (и объект и его атрибуты станут доступны). Итак, является ли это случаем для использования сигналов или мне следует переопределить pre- или post-save(). И почему? Или есть третий вариант, который я пока упустил?

from django.db import models
import pandas as pd


class BaseModel(models.Model):
    objects = models.Manager()

    class Meta:
        abstract = True


class SchoolYear(BaseModel):
    start = models.DateField()
    end = models.DateField()

    def init_days(self):
        current_date = self.start
        delta = timedelta(days=1)
        while current_date <= self.end:
            self.days.add(schoolyear=self, date=current_date, value=0)
            current_date += delta


class Day(BaseModel):
    schoolyear = models.ForeignKey(SchoolYear, on_delete=models.CASCADE)
    date = models.DateField()
    value = models.IntegerField()

Сигналы обычно считаются антипаттерном во всех случаях, кроме нескольких. Вы можете достичь вышеописанного читабельным способом, переопределив функцию сохранения для вашей модели года и используя bulk_create для создания большого количества подобных объектов, что даст вам что-то вроде:

class SchoolYear(BaseModel):
    start = models.DateField()
    end = models.DateField()

    def save(self):
        #see if this is a new year being created by checking for an ID
        being_created = self.pk is None
        #save it anyway (after this it does have an ID)
        super().save(*args, **kwargs)
        #test if this is a newly created year and create days if so
        if being_created:
            current_date = self.start
            delta = timedelta(days=1)
            days = []
            #create a list of days for creation
            while current_date <= self.end:
                days.append(Day(schoolyear=self, date=current_date, value=0))
                current_date += delta
            #use bulk_create to create the list of days efficiently.
            Day.objects.bulk_create(days)
Вернуться на верх