Код для отображения таблицы, связанной с Django (Reverse), выбрасывает ошибку

Я совсем новичок в Django и изучаю раздел Models в Django, следуя официальному учебнику. Я также создал свой собственный проект и пытаюсь применить похожие концепции.

Это мой models.py;

from django.db import models
    
class Experience(models. Model):

    o01_position    = models.CharField(     max_length = 50     )
    o02_year_in     = models.DateField(     null = True)
    o03_year_out    = models.DateField(     null = True)
    o04_project     = models.CharField(     max_length = 100    )
    o05_company     = models.CharField(     max_length = 50     )
    o06_location    = models.CharField(     max_length = 50     )

    def __str__(self):
        return self.o01_position

class Prjdesc(models.Model):

    o00_key         = models.ForeignKey(    Experience,         on_delete = models.CASCADE)
    o07_p_desc      = models.CharField(     max_length = 250    )

    def __str__(self):
        return self.o07_p_desc

class Jobdesc(models.Model):

    o00_key         = models.ForeignKey(    Experience,         on_delete = models.CASCADE)
    o08_job_desc    = models.CharField(     max_length = 250    )

    def __str__(self):
        return self.o08_job_desc

Теперь, когда я запускаю нижеприведенную команду в оболочке python / Django, она выполняется, как и ожидалось, с соответствующими данными.

>>> x = Experience.objects.get( pk = 2 )
>>> x
<Experience: Head Office Technical Office Manager>

Следующие два также работают, как ожидалось;

>>> y = Prjdesc.objects.get( pk = 11 )
>>> y
<Prjdesc: Description 1>

>>> x.prjdesc_set.all()
<QuerySet [<Prjdesc: Description 1>, <Prjdesc: Description 2>]>

Однако это выражение ничего не возвращает, хотя должно возвращать связанную с ним запись в Experience Class;

>>> y.experience
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'Prjdesc' object has no attribute 'experience'

Подскажите, пожалуйста, что я упускаю? Заранее спасибо...

Если вы обратите внимание:

c = q.choice_set.create(choice_text='Just hacking again', votes=0)

есть вызов через _set. Но вовсе нет:

q = Question.objects.get(pk=1)

следует:

q.choice# which will throw the same error

Используя первичную модель, вы можете получить связанные с ней данные из вторичной модели. Для этого в первичной модели по умолчанию создается специальное свойство (объект) с именем secondary model_set. В вашем случае, например:

x = Experience.objects.get(pk=1)
x.prjdesc_set.all()

То есть, мы получаем все значения вторичной модели при pk=1 первичной (доступ "один-ко-многим").

Если вам нужно получить значение из первичной модели из вторичной модели, то, как уже говорилось выше:

Prjdesc.objects.get(id=1).o00_key.o01_position

В этом случае используется get, то есть значение должно быть одно, если ожидается больше, то следует применить filter.

Как вы упомянули в одном из комментариев выше:

Странно, но он возвращает это; Traceback (последнее последнее обращение): File "", line 1, in AttributeError: 'Prjdesc' object has no attribute 'experience'.

.

Вам просто нужно писать c.o00_key, а не c.experience, вы путаете с официальными документами, они дают имя поля также как experince.

Обычно ForeignKey создается с использованием имени модели в smallcase, а related_name устанавливает имя модели как префикс и _set как суффикс, поэтому в вашем случае это будет prjdesc_set или вы можете переопределить это, используя ForeignKey.related_name в поле.

С вашими текущими моделями используйте следующее:

>>> x = Experience.objects.get(pk=2)
>>> x
<Experience: Head Office Technical Office Manager>

>>> c = x.prjdesc_set.create(o07_p_desc='Description 5')
>>> c
<Prjdesc: Description 5>

>>> c.o00_key
>>> c
<Experience: Head Office Technical Office manager>

Примечание: Также лучше использовать f stings в методе __str__(), поэтому в вашем models.py:


class Experience(models.Model):
    ...
    ...
    def __str__(self):
        return f"{self.o01_position}"

class Prjdesc(models.Model):
    ...
    ...
    def __str__(self):
        return f"{self.o07_p_desc}"

class Jobdesc(models.Model):
    ...
    ...
    def __str__(self):
        return f"{self.o08_job_desc}"
Вернуться на верх