Django: Связывание моделей в разных приложениях приводит к ошибке циклического импорта
В моем проекте есть два приложения с именами quiz_app_teacher и accounts многие модели из этих файлов связаны друг с другом, но когда я пытаюсь мигрировать, я получаю эту ошибку
File "F:\self\quiz_site\quiz_app_teacher\models.py", line 2, in from accounts import models as account_models Файл "F:\self\quiz_site\accounts\models.py", строка 13, in class Student(models.Model): File "F:\self\quiz_site\accounts\models.py", line 15, in Student quizzes = models.ManyToManyField(quiz_models.Quiz) AttributeError: partially initialized module 'quiz_app_teacher.models' has no атрибута 'Quiz' (скорее всего, из-за циклического импорта)
quiz_app_teacher/models.py
from django.utils import timezone
from accounts import models as account_models
from django.db import models
# Create your models here.
ANSWER_CHOICES = (
('A', 'A'),
('B', 'B'),
('C','C'),
('D','D'),
)
class Quiz(models.Model):
#https://www.sankalpjonna.com/learn-django/the-right-way-to-use-a-manytomanyfield-in-django
name=models.CharField(max_length=250)
quiz_id = models.CharField(max_length=300,)
created_date = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(account_models.User, on_delete=models.CASCADE,related_name='quizzes')
#Using related_names Author.quizzes.all()
#will list all the quizzes which are made by that author.
course = models.ForeignKey(account_models.Course, on_delete=models.CASCADE, related_name='quizzes')
def save(self, *args, **kwargs):
#override default save method to do something before saving object of model
if not self.quiz_id:
self.quiz_id = self.name+"-"+self.created_date.strftime("%M%S") #TODO:Edit this
super(Quiz, self).save(*args, **kwargs)
def __str__(self):
return self.name
class result(models.Model):
#quiz=models.OneToOneField(Quiz,on_delete=models.CASCADE)
student=models.ForeignKey(account_models.Student , on_delete=models.CASCADE,related_name='my_results')#maybe use account_models.User
quiz=models.ForeignKey(Quiz, on_delete=models.CASCADE, related_name='results')
points=models.IntegerField()
def __str__(self):
return f"Student name: { str(self.student)} Points:{ str(self.points)}"
class Question(models.Model):
quiz = models.ForeignKey(Quiz, on_delete=models.CASCADE, related_name='questions')
#quiz=models.ForeignKey(Quiz, on_delete=models.CASCADE)
question=models.CharField(max_length=300,)
A = models.CharField(max_length=200,)
B = models.CharField(max_length=200,)
C = models.CharField(max_length=200,)
D = models.CharField(max_length=200,)
answer = models.CharField(max_length=200,choices=ANSWER_CHOICES,default='A')
question_number=models.IntegerField()
def __str__(self):
return self.question
accounts/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
import quiz_app_teacher.models as quiz_models
# Create your models here.
class Course(models.Model):
name = models.CharField(max_length=30)
Year=models.IntegerField()
def __str__(self):
return self.name
class User(AbstractUser):
is_teacher = models.BooleanField(default=False)
class Student(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
quizzes = models.ManyToManyField(quiz_models.Quiz)
course = models.ForeignKey(Course,on_delete=models.CASCADE, related_name='class_students')
def __str__(self):
return self.user.username
class Teacher(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
quizzes = models.ManyToManyField(quiz_models.Quiz)
def __str__(self):
return self.user.username
Если я пытаюсь определить отношения, используя
quizzes = models.ManyToManyField(to='quiz_models.Quiz')
SystemCheckError: Проверка системы выявила некоторые проблемы:
ERRORS: accounts.Student.quizzes: (fields.E300) Field definines a отношение с моделью 'quiz_models.Quiz', которая либо не установлена, или является абстрактной. accounts.Student.quizzes: (fields.E307) Поле accounts.Student.quizzes было объявлено с ленивой ссылкой на 'quiz_models.quiz', но приложение 'quiz_models' не установлено. accounts.Student_quizzes.quiz: (fields.E307) Поле accounts.Student_quizzes.quiz было объявлено с ленивой ссылкой на quiz_models.quiz', но приложение 'quiz_models' не установлено.
.
Вы можете удалить импорт и ссылаться на свои модели ForeignKey следующим образом:
models.ForeignKey('account_models.Course', ...)
Это позволит вам запускать миграции без кругового импорта
https://docs.djangoproject.com/en/4.0/ref/models/fields/#django.db.models.ForeignKey