Django/Python 循环模型引用

15

好的,所以我试图编写结构良好的代码,而不是把所有东西都混在一起放在一个django应用程序中。我的问题是,我有3个应用程序,每个应用程序都引用下一个应用程序的1个模型。基本上我有一个无限循环,App A 需要知道 B.models.something1,App B 需要知道 C.models.Somthing2,而App C需要知道A.models.something3。当然,这将无法运行,对于那些想知道这是否真的是问题的人: )。是否有类似于Python预声明类的东西,以便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

学生/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)

学校/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


导入循环并不一定是问题。但是如果没有更多的代码,我们就无法弄清楚它到底是什么。 - Ignacio Vazquez-Abrams
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')

我不了解PyCheckMate,但是如果你的Django应用程序可以工作,而且修复方法是文档化的Django技术,那么我的猜测是故障在PyCheckMate中。 - Michael Dunn
结果发现这不起作用。为什么syncb 起作用显然是因为应用程序不知何故从我的设置文件中删除了(考虑到我没有编辑它,而且我是项目中唯一的人,我也不知道发生了什么)。 - UserZer0
真是一个打击!从你描述的问题来看,模型字符串应该有效。如果不行,一定有其他问题。你能否尝试从你的三个应用程序中删除两个,然后逐步添加回来,直到抛出异常?你的错误信息还有其他线索吗?我遇到了类似于你的错误,当我尝试在管理网站上注册模型时(管理正在尝试在模型准备好进行验证之前验证模型) - Michael Dunn
3
您需要包含应用程序名称,因此不要使用models.ForeignKey('Location'),而应使用models.ForeignKey('teacher.Location') - Bran Handley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接