max
max

Reputation: 10464

Making a custom table with columns that are query results

What I want to achieve is to make load one of my django models into a table and add some columns where the additional columns are queries based on 2 of the cells in the row. For example if the Person model has first name and last name, an additional column would be the result of "select top 1 from another_table where fname=fname and lname=lname"

I tried using django-tables2 and here is my code:

#models.py:
from django.db import models

class Person(models.Model):
    fname = models.CharField(max_length=10)
    lname = models.CharField(max_length=10)
    age = models.IntegerField()

    def __unicode__(self):
        return '%s %s : %i' % (self.fname, self.lname, self.age)

class Map(models.Model):
    person = models.ForeignKey(Person)
    info = models.CharField(max_length=10)

    def __unicode__(self):
        return str(self.person)

# views.py
from django.shortcuts import render
from .models import Person
from django_tables2   import RequestConfig
from .models  import Person
from .tables  import PersonTable

def people(request):
    table = PersonTable(Person.objects.all())
    RequestConfig(request).configure(table)
    return render(request, 'people.html', {'people': table})

#tables.py:
import django_tables2 as tables
from .models import Person

class PersonInfo(tables.Column):
    def render(self, value):
        return str(value) # <<====== this is later going to be my query

class PersonTable(tables.Table):
   info = PersonInfo()
   selection = tables.CheckBoxColumn(accessor="pk", orderable=False)

   class Meta:
       model = Person

There are 3 problems and any help is appreciated:

enter image description here

Upvotes: 0

Views: 582

Answers (1)

KhoPhi
KhoPhi

Reputation: 9527

Below is how I understand your question, and this is how I would go about it:

# models.py

class Person(models.Model):
    name = models.CharField(max_length=100)
    age = models.IntergerField()

class Info(models.Model):
    the_person = models.ForeignKey(Person)
    info = models.CharField(max_length=200)


# views.py
# I'm using Class Based Views from Generic Views

class PersonDetail(ListView):
    # automatically uses pk of 
    # model specified below as slug
    model = Person

So now in your template, you can have something like this:

# html. Just a rough html below. I hope it gives you the idea. Might not tabulate the data properly, but the point is is to have both model data in templates, then simply use {% for %} loop to list one data in one column or more columns of the table and then whatever model(s) in the other columns.
<table style="width:100%">
  <tr>
    <td>Name</td>
    <td>Age</td> 
    <td>Info</td>
  </tr>
  {% for object in object_list %}
  <tr>
    <td>{{ object.name }}</td>
    <td>{{ object.age }}</td> 
    {% for i in object.the_person.set_all %}
    <td>{{ i.info }}</td>
    {% endfor %}
  </tr>
  {% endfor %}
</table>

If you're looking to retrieve two models 'Non-ForeignKey-ed' to each other, you can use context object. See here

Upvotes: 1

Related Questions