在Django的一个视图中合并来自三个表的数据

时间:2018-07-10 06:52:34

标签: python django postgresql

最近几天,我进行了很多搜索,并找到了一些与此主题相关的惊人答案,而我试图找出答案。但是这些都不对我有用,因为看起来情况与之前发布的答案不同,或者不适用于我的Django版本。所以去了:

我需要从3个表中获取数据并在Web界面上显示某些列。我可以毫无问题地获得一张桌子,但另外两张桌子(由外键链接)似乎无法进入视图。我的代码如下(请注意,我正在学习python和django):

models.py:

class students(models.Model):
    date_created = models.DateTimeField()
    project = models.ForeignKey('projects',models.SET_NULL,blank=True,null=True,)
    name = models.TextField()
    return_date = models.TextField()


class sysinfo(models.Model):
    student = models.ForeignKey('students',models.SET_NULL,blank=True,null=True,)
    machine = models.TextField(blank=True, null=True)
    version = models.TextField(blank=True, null=True)
    platform = models.TextField(blank=True, null=True)
    hostname = models.TextField(blank=True, null=True)

class projects(models.Model):
    project_name = models.TextField()
    date_created = models.DateTimeField()
    date_closed = models.DateTimeField(blank=True, null=True) 

views.py

from django.shortcuts import render
from front.models import students, projects, sysinfo

# Create your views here.
def index(request):
    list_students = students.objects.select_related('projects','sysinfo').order_by('-last_seen')
    return render(request, 'main/home.html',{'students': list_students})

这在Web界面上显示了学生ID,创建日期和返回日期,但是我似乎无法从项目表中获得项目名称,或者从sysinfo中获得系统信息。

我尝试将.values('projects__project_name','sysinfo__hostname'... etc。)添加到views.py select_related行。但是我只得到错误,说我的选择是学生表中的字段。

我已经忘记了我尝试过的所有内容,但是可以肯定地说,到目前为止,对我来说文档确实不再有意义。 (事实上​​,我为问这个问题创建了一个SO帐户,应该说很多:P)

先谢谢大家

1 个答案:

答案 0 :(得分:4)

首先让我们修复查询。您想对项目使用select_related,对prefetch_related使用sysinfo(请注意,对于您的模型,student具有零个,一个或多个sysinfo)。另外,您还想将外键字段名称用于selected_related,并将反向关系名称(在您的情况下为默认sysinfo_set)用于sysinfo。最后,您的last_seen模型中没有students字段...

def index(request):
    list_students = students.objects.select_related('project').prefetch_related('sysinfo_set')

现在在您的模板中:

<table>
  {% for student in students %}
  <tr>
    <td>{{ student.name }}</td>
    <td>{{ student.project.project_name }}</td>
    <td>
       {% for sysinfo in student.sysinfo_set.all %}
       {{ sysinfo.host_name }}
       {% endfor %}
    </td>
  </tr>
  {% endfor %}
</table>

作为旁注:Python约定将CamelCase用于类名,而Django约定将单数用于模型名,因此您的模型应命名为StudentProject和{ {1}}。