Циклическая ссылка в модели Django?

Я хотел бы создать две модели: 1) Разговор, в котором хранится ссылка на корневое сообщение с заголовком, и 2) Сообщение, в котором хранится содержимое/текст сообщения и ссылка на кампанию. План состоит в том, чтобы связать сообщения и в конечном итоге создать дерево диалогов. Корневое сообщение в беседе будет действовать как головной (входной) узел связанной сети сообщений.

Ниже то, что я определил в файлах модели (conversations/models.py и messages/models.py соответственно):

from messages.models import Message
class Conversation(models.Model):
    title = models.CharField('Conversation Title', max_length=500)
    created_at = models.DateTimeField(auto_now_add=True)
    composer = models.ForeignKey(User)
    root_message =  models.ForeignKey(Message, null=True, blank=True)

from conversations.models import Conversation
class Message(models.Model):
(foreignkey very likely)
    conversation = models.ForeignKey(Conversation, null=True, blank=True)
    content = models.TextField(db_index=True, max_length=500)
    created_at = models.DateTimeField(auto_now_add=True)

Проблема в том, что когда я запускаю schemamigration messages --auto или schemamigration conversations --auto юга, я сталкиваюсь с такой ошибкой:

    class Campaign(models.Model):
  File "C:\Users\Documents\GitHub\t4s\conversations\models.py", line 11, in Conversation
    from messages.models import Message
ImportError: cannot import name Message

Я полагаю, это потому, что Message и Conversation импортируют друг друга. Но я бы хотел, чтобы каждый экземпляр Message имел связь с Conversation, чтобы я мог ссылаться на заголовок беседы. Есть ли что-то, что я могу сделать, чтобы успешно создать поле Foreignkey в Message и Conversation без изменения структуры моделей? Заранее спасибо за ваши ответы!


person user1330974    schedule 06.08.2015    source источник
comment
возможная копия справочника по круговой модели Django   -  person NightShadeQueen    schedule 06.08.2015
comment
(также см. документацию здесь: docs.djangoproject.com/en/dev /ref/models/fields/#foreignkey , особенно во втором примере)   -  person NightShadeQueen    schedule 06.08.2015
comment
Измените название вашего класса   -  person Gocht    schedule 06.08.2015
comment
@NightShadeQueen, спасибо за предложение! Я внимательно прочитал документ в области, на которую вы указали, и нашел ее полезной. :)   -  person user1330974    schedule 06.08.2015


Ответы (1)


Вы должны использовать строковое значение для ссылки на модели. Однако мне кажется, что обе эти модели должны содержаться в одном приложении. Глядя только на этот фрагмент кода, создается впечатление, что дизайн плохой, поскольку в приложениях не должно быть такой циклической ссылки.

Кроме того, root_message должен быть OneToOneField, поскольку сообщение привязано к одному диалогу, что делает невозможным, чтобы сообщение было корнем более чем одного диалога.

class Conversation(models.Model):
    title = models.CharField('Conversation Title', max_length=500)
    created_at = models.DateTimeField(auto_now_add=True)
    composer = models.ForeignKey(User)
    root_message =  models.ForeignKey('messages.Message', null=True, blank=True)

class Message(models.Model):
    conversation = models.ForeignKey('conversations.Conversation', null=True, blank=True)
    content = models.TextField(db_index=True, max_length=500)
    created_at = models.DateTimeField(auto_now_add=True)
person schillingt    schedule 06.08.2015
comment
Спасибо. Использование строкового значения для ссылки на модель решает проблему циклической ссылки. В определении модели Message я объявил: campaign = models.ForeignKey('campaigns.Campaign', null=True, blank=True). Спасибо за ответ и предложение еще раз. - person user1330974; 06.08.2015
comment
Пожалуйста, рассмотрите также два других моих предложения. - person schillingt; 06.08.2015
comment
да. Сделаю. Думаю, это сделает конфигурацию модели чище. Спасибо. :) - person user1330974; 06.08.2015