Вызовите еще не определенного менеджера модели в предопределенном методе модели Django

#django #django-models

#django #django-модели

Вопрос:

У меня есть 2 модели:

 class Person(models.Model):
    name = models.CharField(max_length=150)

    def __str__(self):
        return self.name


class Message(models.Model):
    sender = models.ForeignKey(Person, related_name='messages_sent', on_delete=models.CASCADE)
    recipient = models.ForeignKey(Person, related_name='messages_recieved', on_delete=models.CASCADE)
    text = models.TextField()

    def __str__(self):
        return self.text
  

Уведомление Person было определено ранее Message .

Я могу сослаться Message перед его определением в, Person если я использую ForeignKey вот так:

 class Person(models.Model):
    myfield = models.ForeignKey('message', on_delete=models.CASCADE)
  

чтобы вызвать еще не определенную модель перед определением.

Но каков наилучший способ вызвать еще не определенную модель в ранее определенном методе модели?

Пример:

 class Person(models.Model):
    name = models.CharField(max_length=150)
    myfield = models.ForeignKey('message', on_delete=models.CASCADE)  # First reference before definition

    def __str__(self):
        return self.name

    def send_message(self, message, recipient):
        sent_message = Message.objects.create(sender=self, recipient=recipient, text=message)  # Second reference before definition in a method somehow?
        return sent_message


class Message(models.Model):
    sender = models.ForeignKey(Person, related_name='messages_sent', on_delete=models.CASCADE)
    recipient = models.ForeignKey(Person, related_name='messages_recieved', on_delete=models.CASCADE)
    text = models.TextField()

    def __str__(self):
        return self.text
  

Есть ли способ сделать это без определения модели Person под моделью сообщения?

Если да, то каков был бы наилучший подход?

Заранее спасибо!

Редактировать:

На самом деле это сработало бы даже при последующем определении модели.

На самом деле я не уверен, почему я получил ошибку раньше.

Комментарии:

1. Вы получали какие-либо ошибки, в частности, NameError: name 'Message' is not defined при доступе Message.objects.create(...) внутри send_message() метода?

2. Хм, по какой-то причине я сделал это в предыдущем проекте, но теперь, похоже, он работает нормально, когда я сделал это в тестовой среде. Это выдало мне ошибку, которая была чем-то вроде «Невозможно использовать неопределенный менеджер модели перед определением» или что-то в этом роде.

3. Python не будет оценивать это утверждение во время запуска проекта, следовательно, NameError не будет, это точно.

4. Кроме того, self.messages_sent это связанный менеджер , а не менеджер по умолчанию . По умолчанию оба являются одинаковыми, но оба также могут отличаться

5. Да, я даже сбросил базу данных, и на самом деле то, что у меня сейчас выше, сработало. К сожалению, я не уверен, как я ранее получал эту ошибку перед раздачей. Я буквально получил его вчера в другом проекте и нашел обходной путь для размещения верхней модели под неопределенной моделью.

Ответ №1:

Разобрался.

Вы можете вызвать неопределенную модель внешнего ключа по ее связанному имени.

В этом случае я мог бы сделать:

 class Person(models.Model): 
    name = models.CharField(max_length=150):

    def __str__(self):
        return self.name

    def send_message(self, recipient, message):
        sent_message = self.messages_sent.create(recipient=recipient, text=message)  # "messages_sent" is the related name of the later defined "Message"'s ForeignKey
        return sent_message

class Message(models.Model):
    sender = models.ForeignKey(Person, related_name='messages_sent', on_delete=models.CASCADE)
    recipient = models.ForeignKey(Person, related_name='messages_recieved', on_delete=models.CASCADE)
    text = models.TextField()

    def __str__(self):
        return self.text