Django models.py循环外键

时间:2021-11-21 21:54:21

I have a django app which basically is just a photo album. Right now I have two models: Image and Album. Among other things, each Album has a foreign key to an Image to be its thumbnail and each Image has a foreign key to the Album it belongs in. However, when I try to use manage.py syncdb or manage.py sqlall I get errors saying the class not defined first in models.py isn't defined when it is used in the first class defined.

我有一个django应用程序,基本上只是一个相册。现在我有两个模型:图像和专辑。除此之外,每个相册都有一个外键,Image为其缩略图,每个Image都有一个外键到它所属的相册。但是,当我尝试使用manage.py syncdb或manage.py sqlall时,我收到错误当在定义的第一个类中使用时,没有定义models.py中未定义的类。

models.py (abridged):

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)

Error I get when I do manage.py sqlall appname:

当我执行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

I get the same error when I switch the order of the classes in models.py except it says 'Album' undefined instead of 'Image' undefined I also tried commenting the dependancy in the first class then uncommenting after everything else was successfully imported but that didn't help. How should I go about making this work? I'm reluctant to make an entire third class Thumb because it will have a lot of the same code as Image I'm also pretty sure I could manually add the foreign key to the database but I want this to be clean and not hackish.

当我在models.py中切换类的顺序时,我得到了相同的错误,除了它说'Album'未定义而不是'Image'未定义我还尝试在第一个类中评论依赖性然后在其他所有成功导入后取消注释但是没有帮助。我该怎么做才能做到这一点?我不愿意制作一个完整的第三类Thumb,因为它会有很多与Image相同的代码我也很确定我可以手动将外键添加到数据库中,但我希望这是干净而不是hackish。

3 个解决方案

#1


38  

You don't actually have a circular reference; the issue is that, at the time you define Album, you haven't defined Image yet. You can fix that by using a string instead:

你实际上没有循环引用;问题是,在您定义相册时,尚未定义图像。您可以通过使用字符串来修复它:

class Album(models.model):
  thumb = models.ForeignKey('Image', null=True, blank=True)

However, in this case, you might want to use a OneToOneField instead of a foreign key. (Note that you'll still have to use the trick with the string, though).

但是,在这种情况下,您可能希望使用OneToOneField而不是外键。 (注意,你仍然必须使用字符串的技巧)。

#2


11  

Use quotes to force a lazy reference:

使用引号强制执行惰性引用:

models.ForeignKey('Image', null=True, blank=True)

Also, ForeignKey.related_name is your friend (avoids back-reference name *es).

此外,ForeignKey.related_name是您的朋友(避免反向引用名称冲突)。

#3


0  

This is old but anyway, i'd like to say that I don't see a reason for attribute album in model Image. In my opinion, it is not really needed.

这已经很老了,但无论如何,我想说我没有在模型Image中看到属性专辑的原因。在我看来,并不是真的需要它。

#1


38  

You don't actually have a circular reference; the issue is that, at the time you define Album, you haven't defined Image yet. You can fix that by using a string instead:

你实际上没有循环引用;问题是,在您定义相册时,尚未定义图像。您可以通过使用字符串来修复它:

class Album(models.model):
  thumb = models.ForeignKey('Image', null=True, blank=True)

However, in this case, you might want to use a OneToOneField instead of a foreign key. (Note that you'll still have to use the trick with the string, though).

但是,在这种情况下,您可能希望使用OneToOneField而不是外键。 (注意,你仍然必须使用字符串的技巧)。

#2


11  

Use quotes to force a lazy reference:

使用引号强制执行惰性引用:

models.ForeignKey('Image', null=True, blank=True)

Also, ForeignKey.related_name is your friend (avoids back-reference name *es).

此外,ForeignKey.related_name是您的朋友(避免反向引用名称冲突)。

#3


0  

This is old but anyway, i'd like to say that I don't see a reason for attribute album in model Image. In my opinion, it is not really needed.

这已经很老了,但无论如何,我想说我没有在模型Image中看到属性专辑的原因。在我看来,并不是真的需要它。