djangodjango-modelsorm

Getting output from joined tables with Django


I have the following example tables in MySQL DB being interacted with Django

class Env(models.Model):
    name = models.CharField()

class ExecutionDetail(models.Model):
    executionid= models.ForeignKey(Execution)
    job= models.CharField()

class Execution(models.Model):
    name= models.ForeignKey(Env)
    executionid= models.CharField()
    envname= models.ForeignKey(Env)

I select data using views

def v_job_history(request, job):
        logger.debug("Calling history jobs")
        jobname=job
        myjobs = ExecutionDetail.objects.filter(job=job)
        template = loader.get_template('history_jobs.html')
        context = {
                'myjobs': myjobs,
        }
        return HttpResponse(template.render(context, request))

Then in my HTML I try and display my data, e.g.

  {% for x in myjobs %}
        <tr>
        <td>{{ x.execution.envname}} </a></td>
        <td>{{ x.execution.name }} </a></td>
        <td>{{ x.job}}</td>
        </tr>
  {% endfor %}

The problem is x.execution.env_name will return Environment object (2) etc.

I have tried x.execution.env_name - returns objects. x.env.name, x.execution.env.name which return nothing.


Solution

  • I would advise to give the ForeignKeys better names, .executionid is not the id of an Execution, it is an Execution object, so:

    class Env(models.Model):
        name = models.CharField(max_length=128)
    
    
    class ExecutionDetail(models.Model):
        execution = models.ForeignKey(Execution, on_delete=models.CASCADE)
        job = models.CharField()
    
    
    class Execution(models.Model):
        name = models.ForeignKey(Env)
        executionid = models.CharField(max_length=128)
        env = models.ForeignKey(Env, on_delete=models.CASCADE)

    then you can use:

    {% for x in myjobs %}
      <tr>
        <td>{{ x.execution.env.name }}</a></td>
        <td>{{ x.execution.name }} </a></td>
        <td>{{ x.job }}</td>
      </tr>
    {% endfor %}

    and boost efficiency with:

    def v_job_history(request, job):
        logger.debug('Calling history jobs')
        jobname = job
        myjobs = ExecutionDetail.objects.filter(job=job).select_related(
            'execution__env'
        )
        context = {
            'myjobs': myjobs,
        }
        return render(request, 'history_jobs.html', context)