我正在为教育学校创建应用程序。学校有RegularSchoolClass类(继承自SchoolClass基础类),还具有LessonSchedule类,该类可跟踪课程的时间表。
特别是,SchoolClass(基类)与LessonSchedule具有多对多关系。特别是,SchoolClass对象应具有48个课程表(例如,第0周,第1周,第2周;一年中有48个课程)。同时,可以由多个SchoolClass对象共享特定的课程表,因此我选择了多对多关系。
我写了一些逻辑,每当用户在管理控制台中更改课程日期时,它都应自动更改链接到该课程的所有LessonScheules。例如,如果一个班级最初是在星期二,并且切换到星期三,那么所有的课程安排都应相应地切换。
奇怪的是,它没有显示在管理控制台中-即使我保存后,它的课程时间表也默认为0。但是在控制台中,self.lesson_schedule.all()。count()显示48。想知道是否有人可以引导我找到正确的答案?
我检查了(Saving Many To Many data via a modelform in Django),由于我已经保存了父对象(我正在使用后保存),因此情况似乎有所不同。
models.py(针对学校课程)
class SchoolClass(TimeStampedModel):
lesson_schedule = models.ManyToManyField('LessonSchedule', null=True, blank=True)
day = models.IntegerField(choices=DAYS, null=True)
start_date = models.DateField(null=True)
def __str__(self):
return '{}'.format(self.lesson_schedule.all().count())
class RegularSchoolClass(DirtyFieldsMixin, SchoolClass):
def save(self, *args, **kwargs):
self.clean()
super().save(*args, **kwargs)
def save_without_signals(self):
setattr(self, '_disable_signals', True)
self.save()
#this correctly prints 48 -> so lesson_schedule should be linked correctly
print(self.lesson_schedule.all().count())
setattr(self, '_disable_signals', False)
@receiver(post_save, sender=RegularSchoolClass)
def post_save_regular_school_class(sender, instance, created, **kwargs):
#https://stackoverflow.com/questions/10840030/django-post-save-preventing-recursion-without-overriding-model-save
#prevents infinite saving
if getattr(instance, '_disable_signals', False):
return
#for new instances or when we have changed the day, we want to update start_date
#and assign lesson schedules
if created or (instance.is_dirty() and 'day' in instance.get_dirty_fields()):
# existing lesson schedule needs to be unlinked
for l in instance.lesson_schedule.all():
instance.lesson_schedule.remove(l)
#assigning new lesson schedule
for l in LessonSchedule.objects.filter(start_date=instance.start_date):
instance.lesson_schedule.add(l)
instance.save_without_signals()
models.py(用于课程表)
#used to track the day for a lesson
#for regular classes, start_date should be the date of the first lesson in the year
class LessonSchedule(models.Model):
start_date = models.DateField()
lesson_index = models.IntegerField()
lesson_date = models.DateField()
class Meta:
unique_together = 'start_date', 'lesson_index')
最佳答案
如果您使用ModelForm,可以尝试这种方式
class GrupoIncidenciaForm(forms.ModelForm):
id = forms.CharField(required=False, widget=forms.HiddenInput())
codigo = forms.CharField(required=True,
label='Código',
widget=forms.TextInput(attrs={'maxlength': '5', 'class': 'text-uppercase'}))
titulo = forms.CharField(required=True, label='Título', widget=forms.TextInput(attrs={'maxlength': '255'}))
class Meta:
model = GrupoIncidencia
fields = '__all__'
labels = {
'tipo': 'Tipo'
}
def clean_codigo(self):
return self.cleaned_data['codigo'].upper().zfill(5)
def __init__(self, *args, **kwargs):
if kwargs.get('instance'):
initial = kwargs.setdefault('initial', {})
initial['incidencias'] = [t.pk for t in kwargs['instance'].incidencias.all()]
forms.ModelForm.__init__(self, *args, **kwargs)
def save(self, commit=True):
instance = forms.ModelForm.save(self, False)
old_save_m2m = self.save_m2m
def save_m2m():
old_save_m2m()
instance.incidencias.clear()
for incidencia in self.cleaned_data['incidencias']:
instance.incidencias.add(incidencia)
self.save_m2m = save_m2m
if commit:
instance.save()
self.save_m2m()
return instance
关于python - Django-多对多关系无法保存,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45058185/