I am getting confused with the usage of related_name in django models, i know that the idea is to give me access to all the fields of a different table with foreignkey i am just not sure how to use it.

My model.py:

class Component(MPTTModel):
    name = models.CharField(max_length=100)
    manufacturer = models.CharField(max_length=100)
    model = models.CharField(max_length=100)
    serial_number = models.CharField(max_length=255)
    price = models.IntegerField()
    note = models.TextField()
    image = models.ImageField(blank=True, null=True,
                              upload_to='components_imgs')
    parent = TreeForeignKey("self", verbose_name=(
        "Parent Component"), blank=True, null=True, related_name='children', on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.id}, {self.name}"

class Job(models.Model):
    job_type = (
        ('I', 'Interval'),
        ('O', 'One time'),
    )
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=100)
    type = models.CharField(max_length=1, choices=job_type)
    interval = models.IntegerField()
    is_critical = models.BooleanField()
    due_date = models.DateField()
    component = models.ForeignKey(
        Component, related_name='jobs', on_delete=models.CASCADE)
    runninghours = models.ForeignKey(
        RunningHours, related_name="RHjobs", on_delete=models.CASCADE)

    def __str__(self):
        return self.name

my view.py:

def worklist(request):
    components = Component.objects.all()
    Component_jobs = components.jobs.all()
    context = {"component":components,
    "Component_jobs":Component_jobs}
    return render(request,"worklist.html",context)

I am trying to understand why these lines give me an error 'TreeQuerySet' object has no attribute 'jobs'

components = Component.objects.all()
Component_jobs = components.jobs.all()

but these lines work just fine,

component = Component.objects.all()
component_id = Component.objects.get(id=pk)
job_id = component_id.jobs.all()

are they not the same but with one i am getting all the jobs for a specific ID and the other i am getting all the jobs for all components?

Edited, My template :

<div class="worklist">
    {%for component in component %}
    <p> {{component.name}} </p>
    <div class="runninghours-table-flex">
        <table class="runninghours-table">
            <thead>
                <tr>
                    <th>Job name</th>
                    <th>Job type</th>
                    <th>Due Date </th>
                    <th>Interval</th>
                    <th>Rank</th>
                    <th>Execute Job</th>
                </tr>
            </thead>
            <tbody>
                {% for c_jobs in component_jobs%}
                <tr>
                    <td>{{c_jobs.name}} </td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                    <td></td>
                </tr>
                {%endfor%}
            </tbody>
        </table>
    </div>
    {%endfor%}
</div>

Assuming you want to display all components in a loop and then display all related jobs for each component in a nested loop, your template should look something like this simplified example

{% for component in components %}
  {{ component }}
  {% for job in component.jobs.all %}
    {{ job }}
  {% endfor %}
{% endfor %}

You should then use prefetch_related to fetch all related jobs for all components in a single query. There is no need to query the jobs in your view

components = Component.objects.all().prefetch_related('jobs')

As the error describes, this code returns a TreeQuerySet object.

components = Component.objects.all()

Trying to call fields like price will result in the same error.

components = Component.objects.all()
Component_jobs = components.price.all()

The reason this code works is because it is called on a specific Component instead of a collection of Components.

component = Component.objects.all()
component_id = Component.objects.get(id=pk)
job_id = component_id.jobs.all()

To get all jobs on a queryset, try using something like .values('jobs') from the queryset api reference

all_jobs = Component.objects.all().values('jobs')