Тестирование Django не распознает dirty_fields?
В одной из моих моделей используются dirty_fields. Метод сохранения обнаруживает, когда поле scale_mode
изменяется. Как только это происходит, он проходит через все связанные объекты grade
и изменяет поле score
для каждого затронутого grade
. Цель - если VSB поменять местами с VSBPLUS, то APP поменять местами с APP+.
модель:
class GradeBookSetup(DirtyFieldsMixin, models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.OneToOneField(
settings.AUTH_USER_MODEL, on_delete=CASCADE)
VSB = 'VSB'
VSBPLUS = 'VSBPLUS'
SCALEMODE = [
('VSB', 'BEG DEV APP EXT'),
('VSBPLUS', 'BEG DEV APP APP+ EXT'),
]
scale_mode = models.CharField(
max_length=7, choices=SCALEMODE, blank=True, default=VSB)
def save(self, *args, **kwargs):
super(GradeBookSetup, self).save(*args, **kwargs)
if self.is_dirty():
dirty_fields = self.get_dirty_fields()
if 'scale_mode' in dirty_fields:
if self.scale_mode == "VSB":
objs = Grade.objects.filter(user=self.user)
for grade in objs:
if grade.score == "APP+":
objs[n].score = "APP"
Grade.objects.bulk_update(objs, ['score'])
elif self.scale_mode == "VSBPLUS":
objs = Grade.objects.filter(user=self.user)
for grade in objs:
if grade.score == "APP":
objs[n].score = "APP+"
Grade.objects.bulk_update(objs, ['score'])
class Grade(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
INCOMPLETE = 'I'
BEGINNING = 'BEG'
DEVELOPING = 'DEV'
APPLYING = 'APP'
APPLYINGPLUS = 'APP+'
EXTENDING = 'EXT'
score = models.CharField(
max_length=4, blank=True, default=INCOMPLETE)
user = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
assessment = models.ForeignKey(
Assessment, on_delete=models.CASCADE, null=True, blank=True)
objective = models.ForeignKey(
Objective, on_delete=models.CASCADE, blank=True)
student = models.ForeignKey(Student, on_delete=models.CASCADE)
cblock = models.ForeignKey(Classroom, on_delete=models.CASCADE, default=1)
Я пишу тесты для этой модели. Каждый из приведенных ниже тестов проходит, кроме последнего, test_scale_mode_change
.
class GradeBookSetupTest(TestCase):
@classmethod
def setUpTestData(cls):
cls.user = get_user_model().objects.create_user(
username='tester',
email='tester@email.com',
password='tester123'
)
cls.gbsetup = GradeBookSetup(
user=cls.user,
scale_mode="VSBPLUS",
)
cls.gbsetup.save()
cls.student = Student.objects.create(
user=student_user,
student_first="Jim",
student_last="Smith",
nickname="Jim S",
fullname="Jim Smith",
student_number=992342,
email="992342@learn.vsb.bc.ca"
)
cls.course = Course.objects.create(
user=cls.user,
course_name="Math8",
grade_level='ELEM',
)
cls.classroom = Classroom(
user=cls.user,
classroom_name='Block 1',
course=cls.course,
)
cls.classroom.students.add(cls.student)
cls.classroom.save()
cls.objective = Objective.objects.create(
user=cls.user,
objective_name='factor.1',
mode='LA',
course=cls.course,
description="Test objective",
)
cls.assessment = Assessment(
user=cls.user,
assessment_name="Quiz1",
course=cls.course,
)
cls.assessment.objectives.add(cls.objective)
cls.assessment.save()
cls.grade = Grade.objects.create(
user=cls.user,
score='APP+',
student=cls.student,
cblock=cls.classroom,
assessment=cls.assessment,
objective=cls.objective
)
def test_gradebooksetup_creation(self):
self.assertEqual(self.gbsetup.scale_mode, "VSBPLUS")
def test_grade_creation(self):
self.assertEqual(self.grade.score, 'APP+')
self.assertNotEqual(self.grade.score, 'DEV')
def test_scale_mode_change(self):
self.gbsetup.scale_mode = 'VSB'
self.gbsetup.save()
print(self.gbsetup.scale_mode)
self.assertEqual(self.grade.score, 'APP')
Я ожидаю, что произойдет то, что `self.gbsetup.scale_mode = 'VSB' должно сработать поле dirty_field в методе сохранения. Это должно изменить результат APP+ на APP. Оператор print подтверждает, что gbsetup == VSB.
Что происходит:
self.assertEqual(self.grade.score, 'APP')
AssertionError: 'APP+' != 'APP'
Я не показал все связанные модели для Grade и GradeBookSetup, я не думаю, что они имеют отношение к этой проблеме. Я могу добавить их, если потребуется.
Возможно, вам потребуется перехватить оценку из базы данных, поскольку изменение происходит в базе данных, но эталонным экземпляром остается тот, который был создан в настройке.
def test_scale_mode_change(self):
self.gbsetup.scale_mode = 'VSB'
self.gbsetup.save()
print(self.gbsetup.scale_mode)
#we have made indirect changes to grade via the gbsetup.save() function that we need to check
self.grade.refresh_from_db()
self.assertEqual(self.grade.score, 'APP')