Django models.py 循环外键
我有一个Django应用,基本上就是一个照片相册。目前我有两个模型:Image
(图片)和Album
(相册)。简单来说,每个Album
都有一个指向Image
的外键,用作缩略图,而每个Image
也有一个外键,指向它所属的Album
。但是,当我尝试使用manage.py syncdb
或manage.py sqlall
时,系统报错说在models.py中第一个定义的类没有定义。
这是我简化后的models.py:
from django.db import models
import os
class Album(models.Model):
thumb = models.ForeignKey(Image, null=True, blank=True)
class Image(models.Model):
image = models.ImageField(upload_to='t_pics/images')
thumb = models.ImageField(upload_to='t_pics/images/thumbs')
album = models.ForeignKey(Album)
当我执行manage.py sqlall appname
时,出现的错误是:
[...]
File "/path/to/file/appname/models.py", line 4, in ?
class Album(models.Model):
File "/path/to/file/appname/models.py", line 5, in Album
thumb = models.ForeignKey(Image, null=True, blank=True)
NameError: name 'Image' is not defined
如果我调换models.py中类的顺序,系统会报同样的错误,只不过这次是说'Album'未定义
,而不是'Image'未定义
。我还尝试过在第一个类中注释掉依赖关系,然后在其他内容成功导入后再取消注释,但这也没有解决问题。我该如何处理才能让它正常工作?我不太想创建一个新的类Thumb
,因为它会有很多和Image
相同的代码。我也很确定我可以手动将外键添加到数据库,但我希望这个过程干净利落,而不是走捷径。
3 个回答
0
这虽然是个老问题,但我想说的是,我觉得在图片模型中没有必要有这个“专辑”属性。在我看来,这个属性其实并不需要。
13
使用引号可以强制使用懒加载引用:
models.ForeignKey('Image', null=True, blank=True)
另外,ForeignKey.related_name 是个好帮手(可以避免反向引用名称冲突)。
46
其实你并没有真正出现循环引用的问题;问题在于,当你定义Album的时候,Image还没有被定义。你可以通过用字符串来解决这个问题:
class Album(models.model):
thumb = models.ForeignKey('Image', null=True, blank=True)
不过在这种情况下,你可能想用OneToOneField,而不是外键。(不过你还是得用字符串的那个小技巧)。