Django Тестовая ассоциация ключей
Я новичок в Django и модульном тестировании.
Я пишу тесты для своего приложения, которое представляет собой обучающую платформу, состоящую из нескольких лабораторий, включающих урок и вопросы (3 разных типа), связь между вопросами и лабораториями осуществляется через внешний ключ.
Я пытаюсь написать тесты, в которых я добавляю лабораторию в базу данных и вопрос с множественным выбором.
Проблема в том, что тесты всегда заканчиваются одной и той же ошибкой:
DETAIL: Key (lab_id)=(1) is not present in table "labs_lab".
Я понимаю смысл предложения, но как это происходит, если я указываю идентификатор для вопросов, чтобы связать их с соответствующей тестовой лабораторией?
Спасибо
Models.py
class Lab(models.Model):
lab_name = models.CharField(max_length=200)
category = models.ForeignKey(Category, unique=True, null=True, on_delete=models.PROTECT)
pub_date = models.DateTimeField('date published')
lab_theory = models.TextField()
def __str__(self):
return self.lab_name
class QuestionMultipleChoice(models.Model):
lab = models.ForeignKey(Lab, on_delete=models.CASCADE)
type = QuestionType.multiplechoice
question = models.CharField(max_length=200,null=True)
option1 = models.CharField(max_length=200,null=True)
option2 = models.CharField(max_length=200,null=True)
option3 = models.CharField(max_length=200,null=True)
option4 = models.CharField(max_length=200,null=True)
answer = models.IntegerField(max_length=200,null=True)
def __str__(self):
return self.question
@property
def html_name(self):
return "q_mc_{}".format(self.pk)
@property
def correct_answer(self):
correct_answer_number = int(self.answer)
correct_answer = getattr(self, "option{}".format(correct_answer_number))
return correct_answer
def check_answer(self, given):
return self.correct_answer == given
test.py
class TestData(TestCase):
@classmethod
def setUpTestData(cls):
past_date = date(1997, 3, 2)
future_date = date(2050, 3, 2)
Lab.objects.create(lab_name="testlab", pub_date=datetime.now(), lab_theory="test theory")
Lab.objects.create(lab_name="test lab past question", pub_date=past_date, lab_theory="test lab past question")
Lab.objects.create(lab_name="test lab future question", pub_date=future_date, lab_theory="test lab future question")
class QuestionIndexViewTests(TestCase):
def test_no_questions(self):
"""
If no questions exist, an appropriate message is displayed.
"""
response = self.client.get(reverse('labs:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "No labs are available.")
self.assertQuerysetEqual(response.context['latest_question_list'], [])
def test_past_question(self):
"""
Questions with a pub_date in the past are displayed on the
index page.
"""
past_question = QuestionMultipleChoice.objects.create(question='This is a test question', option1='1', option2='2', option3='3', option4='4', answer='1', lab_id=2)
response = self.client.get(reverse('labs:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
[past_question],
)
UPDATE:
Обновление: Я изменил тест, и дал "QuestionMultipleChoice" различные параметры:
question1 = QuestionMultipleChoice.objects.create(lab=1, question='This is a test question', option1='1', option2='2', option3='3', option4='4', answer='1')
Результатом теперь является:
ValueError: Cannot assign "1": "QuestionMultipleChoice.lab" must be a "Lab" instance.
ValueError: Невозможно присвоить значение "1": "QuestionMultipleChoice.lab" должен быть экземпляром "Lab".
это означает, что атрибут лаборатории пытается получить экземпляр лаборатории, вы можете предоставить экземпляр лаборатории, чтобы назначить экземпляр лаборатории, вы должны сделать вот так
lab1 = Lab.objects.create(lab_name="testlab", pub_date=datetime.now(), lab_theory="test theory")
QuestionMultipleChoice.objects.create(question='This is a test question', lab=lab1)