Цилиндрический внешний ключ Django models.py - PullRequest
17 голосов
/ 10 сентября 2010

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

Ответы [ 3 ]

38 голосов
/ 10 сентября 2010

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

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

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

12 голосов
/ 10 сентября 2010

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

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

Кроме того, ForeignKey.related_name - ваш друг (избегает столкновений с обратными ссылками).

0 голосов
/ 20 ноября 2013

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...