Django/Python 循环模型引用

15 投票
1 回答
6074 浏览
提问于 2025-04-16 10:42

好的,我正在努力写一些结构清晰的代码,想要把不同的django应用分开,而不是把所有东西都放在一个地方。我的问题是,我有三个应用,每个应用都需要引用下一个应用中的一个模型。简单来说,我就形成了一个无尽的循环:应用A需要知道B中的某个模型,应用B需要知道C中的某个模型,而应用C又需要知道A中的某个模型。这当然是无法运行的,想知道这是不是个问题的人可以放心,这确实是个问题 :)。有没有什么方法可以提前声明这些类,让Python知道这些类其实是存在的呢?

谢谢。

编辑:更多代码:

不幸的是,我项目的性质和模型是保密的,所以我得把名字改成完全不同的,但代码会保持不变。

teacher/models.py

 from django.db import models
 from myapp.student.models import *
 from django.contrib.auth.models import User
 class Teacher(models.Model):
     """(description)"""
     user = models.ForeignKey(User)
     name = models.CharField(max_length=100)
     phone = models.CharField(max_length=13)
     phone_ext = models.CharField(blank=True, max_length=5)
     fax = models.CharField(blank=True, max_length=13)
     fax_ext = models.CharField(blank=True, max_length=100)
     url = models.URLField(blank=True, verify_exists=True)
     complaint = models.ManyToManyField(Complaint)
     city = models.CharField(blank=True, max_length=100)
     state = models.CharField(blank=True, max_length=100)
     postal_code = models.CharField(blank=True, max_length=15)
     location = models.ManyToManyField(Location)
     def __unicode__(self):
         return self.name
 class Location(models.Model):
     """(description)"""
     city = models.CharField(blank=True, max_length=100)
     state = models.CharField(blank=True, max_length=100)
     country = models.CharField(blank=False, max_length=100)
     def __unicode__(self):
         return self.city + ", " + self.state +", "+self.country

student/models.py

 from django.db import models
 from django.contrib.auth.models import User
 from myapp.school.models import School

 class Student(models.Model):
     """(Student description)"""
     user = models.ForeignKey(User)
     country = models.CharField(max_length=100)
     state = models.CharField(max_length=100)
     city = models.CharField(max_length=100)
     locale = models.CharField(blank=False, max_length=5)
     learningtype = models.CharField(blank=True, max_length=100)
     sites = models.TextField(blank=True)
     def __unicode__(self):
         return str(self.user)

 class Complaint(models.Model):
     """(Complaint description)"""
     student = models.ForeignKey(Student)
     site = models.ForeignKey(School)
     complaint = models.TextField(blank=False)
     def __unicode__(self):
         return str(self.site)

school/models.py

 from django.db import models
 from myapp.teacher.models import Location
 class School(models.Model):
     """(School description)"""
     name = models.CharField(max_length=100)
     url = models.URLField(verify_exists=True)
     img = models.ImageField(upload_to="casion_img/")
     rating = models.FloatField()
     description = models.CharField(blank=True, max_length=300)
     goodstanding = models.BooleanField(default=True)
     location = models.ForeignKey(Location)
     def __unicode__(self):
         return self.name

所以我遇到的问题是:

文件 "/Users/userzero/django/myapp/school/models.py",第2行,试图从 teacher.models 导入 Location 文件 "/Users/userzero/django/myapp/teacher/models.py",第2行,试图从 student.models 导入 Complaint 文件 "/Users/userzero/django/myapp/student/models.py",第3行,试图从 school.models 导入 School 文件 "/Users/userzero/django/myapp/casino/models.py",第2行,试图从 teacher.models 导入 Location 导入错误:无法导入名称 Location

1 个回答

37

来自文档

如果你想引用在另一个应用中定义的模型,可以明确地使用完整的应用标签来指定模型。例如,如果上面的Manufacturer模型是在另一个叫做production的应用中定义的,你需要这样写:

class Car(models.Model):
     manufacturer = models.ForeignKey('production.Manufacturer')

这种引用方式在解决两个应用之间的循环导入依赖时非常有用。

所以对于你的应用,试着把例如

 location = models.ForeignKey(Location) 

改成

 location = models.ForeignKey('Location')

请注意,如果这个模型在不同的应用中,你也需要指定这一点(感谢@Bran指出这一点),例如:

 location = models.ForeignKey('teacher.Location')

撰写回答