В модели создаются дни для каждого созданного года
Я новичок в 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)