Подтвердить что ты не робот

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' undefined вместо 'Image' undefined. Я также пробовал комментировать зависимость в первом классе, а затем раскомментировать после того, как все остальное было успешно импортировано, но это не помогло. Как я должен заниматься этой работой? Я не хочу делать весь третий класс Thumb, потому что у него будет много того же кода, что и Image. Я также уверен, что могу вручную добавить внешний ключ в базу данных, но я хочу, чтобы это было чисто и не хакировать.

4b9b3361

Ответ 1

На самом деле у вас нет круговой ссылки; проблема в том, что в то время, когда вы определяете альбом, вы еще не определили изображение. Вы можете исправить это, используя вместо этого строку:

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

Однако в этом случае вместо внешнего ключа вы можете использовать OneToOneField. (Обратите внимание, что вам все равно придется использовать трюк со строкой).

Ответ 2

Используйте цитаты, чтобы заставить ленивую ссылку:

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

Кроме того, ForeignKey.related_name - ваш друг (избегает конфликтов имен back-reference name).

Ответ 3

Это старый, но в любом случае, я бы хотел сказать, что я не вижу причины для альбома атрибутов в модели Image. На мой взгляд, это действительно не нужно.