Django ORM 从两个或更多模型中选择列

Posted

技术标签:

【中文标题】Django ORM 从两个或更多模型中选择列【英文标题】:Django ORM Select Column From Two Model or More 【发布时间】:2021-04-08 13:28:21 【问题描述】:

我想从两个或更多模型中选择带有 django orm 的列。

SELECT nim, k.kode, s.nama, sks, nilai, th_ajaran FROM mahasiswa_khs k, mata_kuliah_si s WHERE k.kode = s.kode AND nim = %s

这是我的代码

khs = Khs.objects.filter(nim=nim).values_list('kode').union(SI.objects.all().values_list('kode'))

但是,我在模板中调用它没有显示

这是我的模板:

% for khs in khs %
                        <tr>
                          <td>forloop.counter</td>
                          <td>khs.kode</td>
                          <td>khs.nama</td>
                          <td>khs.sks</td>
                          <td class="vertical-align-mid">khs.nilai</td>
                          <th>khs.th_ajaran</th>
                        </tr>
                        % endfor %

还有观点:

khs = Khs.objects.filter(nim=nim).union(SI.objects.all().values_list('kode'))
context =
        'khs' : khs,
    
    return render(request, 'mahasiswa/mahasiswa.html',context)

【问题讨论】:

使用.values_list('kode')的原因是什么? 要合并该模型,我没有收到错误“使用的 SELECT 语句具有不同数量的列”) 明白了。请在您的问题中包含模板和视图。 是的,有我的模板和视图 【参考方案1】:

当您使用 .values_list.values 时,您是在告诉 ORM 只选择这些列。根据docs:

这与 values() 类似,只是不是返回 字典,它在迭代时返回元组。每个元组 包含传入的相应字段或表达式的值 values_list() 调用——所以第一项是第一个字段,等等。 例如:

from django.db.models.functions import Lower
Entry.objects.values_list('id', Lower('headline')) <QuerySet [(1, 'first entry'), ...]>```

由于您使用的是values_list,这意味着您要提取一个如下所示的数据集:[('kode_value_1',), ('kode_value_2', ), ...]。在您的模板中,您将使用:

% for values in khs %
     values.0 
% endfor %

为了提取其他字段,例如 nama,您需要调整查询集:

khs = ( Khs.objects.filter(nim=nim) .values_list('kode', 'nama') .union(SI.objects.all().values_list('kode', 'nama')) )

然后在您的模板中,您将拥有:

% for values in khs %
    kode:  values.0 
    nama:  values.1
% endfor %

如果你想使用字段名,那么你应该使用values()而不是values_list(),这样你的模板标签就是 values.kode

SI 没有nama 字段的情况下,您可以进行注释以设置一个虚拟值,以便进行联合。

from django.db.models import Value, CharField
khs = (
    Khs.objects.filter(nim=nim)
    .values_list('kode', 'nama')
    .union(
        SI.objects
        .annotate(nama=Value(None, output_field=CharField()))
        .values_list('kode', 'nama')
    )
)

我猜nama 是一个 CharField。您可能需要根据数据模型的需要进行更改。如果您愿意,注释方法也可以完全避免使用.values_list

【讨论】:

以上是关于Django ORM 从两个或更多模型中选择列的主要内容,如果未能解决你的问题,请参考以下文章

Django ORM按两个相关模型的最大列值过滤

Django模型层之更多操作

Django ORM:选择相关集

使用 django ORM 进行高级选择

如何在fuelPHP Orm模型中选择MAX或COUNT

Django ORM 类似于 Pony ORM 中的选择查询