Skip to content
Advertisement

Code to display Django (Reverse) related table throws error

I’m quite new to Django and practicing Models section of Django by following its official tutorial. I also created a project of my own and try to apply similar concepts.

This is my 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

Now when I run below command in Python/Django shell it runs as expected with the related data.

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

Below two also work as expected:

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

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

However this expression does not return anything although it should return its related record in Experience Class.

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

Could you tell me what I am missing here?

Advertisement

Answer

As you mentioned in one of the comments above:

Strangely it returns this; Traceback (most recent call last): File “”, line 1, in AttributeError: ‘Prjdesc’ object has no attribute ‘experience’.

You simply need to write c.o00_key not c.experience, you confused with official docs, they give their field name also as experince.

Generally, ForeignKey is created using model name in smallcase while defining field, and the related_name sets to model name as prefix and _set as suffix by default, so it will be prjdesc_set in your case or you can override it by using ForeignKey.related_name in the field.

With your current models use this:

>>> 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>

Note: Also it’s better to use f stings in the __str__() method, so in your 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}"
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement