如何在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)
关键逻辑说明
- 参数修正:把原来的
id替换为传入的nsn参数,确保过滤条件和用户输入一致。 - 单条数据复制:当
u_m只有1行时,先把它转成干净的字典(去掉Django自带的私有字段),然后遍历每一条c_m数据,将u_m的字段合并进去,完美实现“单条数据复制到多行”的需求。 - 通用内连接:如果
u_m不是单条数据,通过比对NSN值实现基础内连接,只保留两个表中NSN匹配的记录组合。 - 字典合并:用
{**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
相关产品推荐
相关产品推荐

