You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Django中创建基于NSN字段实现两表内连接的QuerySet对象

Django非托管模型基于NSN的内连接与数据合并实现

刚好碰到过类似的非托管模型关联场景,我来帮你搞定这个需求:

首先得先修正你现有视图里的小问题——你传入的参数是nsn,但代码里误用了id,这会导致过滤条件完全不匹配,先把这个坑填上。另外因为这两个是非托管模型(managed=False),没法直接用Django ORM的关联查询(比如select_related),所以我们需要手动处理数据的合并逻辑,尤其是单条数据对应多条的复制场景。

完整视图实现代码

from django.shortcuts import render
from .models import DibbsSpiderDibbsMatchedProductFieldsDuplicate, DibbsSpiderSolicitation

def inner(request, nsn):
    # 修正参数:用传入的nsn替代原来的id,确保过滤逻辑正确
    u_m_queryset = DibbsSpiderDibbsMatchedProductFieldsDuplicate.objects.filter(nsn2__icontains=nsn)
    c_m_queryset = DibbsSpiderSolicitation.objects.filter(nsn__icontains=nsn)
    
    combined_data = []
    
    # 优先处理u_m仅1行、c_m多行的核心需求场景
    if u_m_queryset.count() == 1:
        # 取出唯一的u_m数据,转成字典并清理Django模型的私有字段(比如_state)
        u_m_raw = u_m_queryset.first().__dict__
        u_m_cleaned = {k: v for k, v in u_m_raw.items() if not k.startswith('_')}
        
        # 遍历每一条c_m数据,把u_m的字段复制进去
        for c_m_item in c_m_queryset:
            c_m_raw = c_m_item.__dict__
            c_m_cleaned = {k: v for k, v in c_m_raw.items() if not k.startswith('_')}
            # 合并两个字典,c_m字段如果和u_m重复会保留c_m的(可根据需求调换顺序)
            merged_record = {**u_m_cleaned, **c_m_cleaned}
            combined_data.append(merged_record)
    else:
        # 兼容其他场景:实现基础的内连接逻辑,只保留NSN匹配的记录组合
        u_m_nsns = set(u_m_queryset.values_list('nsn2', flat=True))
        for c_m_item in c_m_queryset:
            if c_m_item.nsn in u_m_nsns:
                matched_u_m = u_m_queryset.filter(nsn2__icontains=c_m_item.nsn).first()
                if matched_u_m:
                    u_m_cleaned = {k: v for k, v in matched_u_m.__dict__.items() if not k.startswith('_')}
                    c_m_cleaned = {k: v for k, v in c_m_item.__dict__.items() if not k.startswith('_')}
                    merged_record = {**u_m_cleaned, **c_m_cleaned}
                    combined_data.append(merged_record)
    
    context = {'obj': combined_data}
    return render(request, "a.html", context)

关键逻辑说明

  1. 参数修正:把原来的id替换为传入的nsn参数,确保过滤条件和用户输入一致。
  2. 单条数据复制:当u_m只有1行时,先把它转成干净的字典(去掉Django自带的私有字段),然后遍历每一条c_m数据,将u_m的字段合并进去,完美实现“单条数据复制到多行”的需求。
  3. 通用内连接:如果u_m不是单条数据,通过比对NSN值实现基础内连接,只保留两个表中NSN匹配的记录组合。
  4. 字典合并:用{**dict1, **dict2}语法合并字段,如果你希望u_m的字段覆盖重复的c_m字段,调换两个字典的顺序即可。

模板中使用合并后的数据

在a.html里可以直接遍历obj展示数据:

{% for record in obj %}
    <div class="record-item">
        <p>NSN: {{ record.nsn }}</p>
        <p>供应商: {{ record.supplier }}</p>
        <p>行项目数: {{ record.line_items }}</p>
        <!-- 其他字段按需渲染 -->
    </div>
{% endfor %}

内容的提问来源于stack exchange,提问作者Rikky Bhai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:54:46