【问题标题】:How to create a django queryset object for inner join?如何为内部连接创建一个 django 查询集对象?
【发布时间】:2021-12-30 09:23:30
【问题描述】:

我有两张桌子。

class DibbsSpiderDibbsMatchedProductFieldsDuplicate(models.Model):
    nsn = models.TextField()
    nsn2 = models.TextField()
    cage = models.TextField()
    part_number = models.TextField()
    company_name = models.TextField(blank=True, null=True)
    supplier = models.TextField(db_column='Supplier', blank=True, null=True)  # Field name made lowercase.
    cost = models.CharField(db_column='Cost', max_length=15, blank=True, null=True)  # Field name made lowercase.
    list_price = models.CharField(db_column='List_Price', max_length=15, blank=True, null=True)  # Field name made lowercase.
    gsa_price = models.CharField(db_column='GSA_Price', max_length=15, blank=True, null=True)  # Field name made lowercase.
    hash = models.TextField()
    nomenclature = models.TextField()
    technical_documents = models.TextField()
    solicitation = models.CharField(max_length=32)
    status = models.CharField(max_length=16)
    purchase_request = models.TextField()
    issued = models.DateField()
    return_by = models.DateField()
    file = models.TextField()
    vendor_part_number = models.TextField()
    manufacturer_name = models.TextField(blank=True, null=True)
    product_name = models.TextField(blank=True, null=True)
    unit = models.CharField(max_length=15, blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'dibbs_spider_dibbs_matched_product_fields_duplicate'


class DibbsSpiderSolicitation(models.Model):
    line_items = models.IntegerField()
    nsn = models.TextField()
    nomenclature = models.TextField()
    technical_documents = models.TextField()
    purchase_request = models.TextField()

    class Meta:
        managed = False
        db_table = 'dibbs_spider_solicitation'

对于列nsn 上的两个表的内部连接,等效的 django 查询是什么? 我的意见功能会像

def inner(request,nsn):
    u_m =  DibbsSpiderDibbsMatchedProductFieldsDuplicate.objects.filter(nsn2__icontains=id)
    c_m = DibbsSpiderSolicitation.objects.filter(nsn__icontains=id)
    obj = .......................
    context = {'obj':obj}
    return render(request,,"a.html",context)

查询集应该根据共同的nsn返回两个表的组合。

obj 应该返回u_mc_m 的组合。如果u_m 仅包含一行而c_m 包含许多行,则 obj 必须复制 u_m 的值。

【问题讨论】:

    标签: python django django-views django-queryset


    【解决方案1】:

    您可以尝试一些选项:

    1. 添加外键约束并按照this post使用select_related
    2. this stackoverflow post 中提到的原始查询以及custom joins 的另一篇文章

    3。按照以下逻辑使用 IN 查询:

    DibbsSpiderDibbsMatchedProductFieldsDuplicate.objects.filter(
            nsn2__in=DibbsSpiderSolicitation.objects.filter(nsn__icontains='text_to_search').values('origin'))
    

    【讨论】:

      【解决方案2】:

      首先,伟大的模型名称。让我们给它们起别名: DibbsSpiderDibbsMatchedProductFieldsDuplicate 是 Apples; DibbsSpiderSolicitation 是 Oranges

      inner_qs = Apples.objects.all().extra(
          tables=("yourapp_oranges",),
          where=("yourapp_apples.nsn=yourapp_oranges.nsn",),
      )
      

      文档中提到此 api 将被弃用: https://docs.djangoproject.com/en/4.0/ref/models/querysets/#extra

      【讨论】:

        【解决方案3】:

        选项 #1 - 引入 ForeignKey(推荐):

        DibbsSpiderDibbsMatchedProductFieldsDuplicate类下添加:

        fkey = models.ForeignKey('DibbsSpiderSolicitation')
        

        然后您可以轻松访问他们的加入:

        obj = DibbsSpiderDibbsMatchedProductFieldsDuplicate.Objects.filter(fkey__nsn).select_related()
        

        现在你可以选择你想用nsn2做什么

        选项 #2 - 没有 ForeigKey:

        原始 SQL:

        obj = DibbsSpiderDibbsMatchedProductFieldsDuplicate.objects.extra(where = ['''SELECT *
        FROM DibbsSpiderSolicitation
        INNER JOIN DibbsSpiderDibbsMatchedProductFieldsDuplicate
        ON DibbsSpiderSolicitation.nsn = DibbsSpiderDibbsMatchedProductFieldsDuplicate.nsn2;'''])
        # or
        obj = DibbsSpiderDibbsMatchedProductFieldsDuplicate.objects.raw('''SELECT *
        FROM DibbsSpiderSolicitation
        INNER JOIN DibbsSpiderDibbsMatchedProductFieldsDuplicate
        ON DibbsSpiderSolicitation.nsn = DibbsSpiderDibbsMatchedProductFieldsDuplicate.nsn2;''')
        

        使用过滤器:

        obj = DibbsSpiderSolicitation.objects.filter(nsn__in=DibbsSpiderDibbsMatchedProductFieldsDuplicate.objects.nsn2)
        

        抱歉,我无法测试任何内容。

        【讨论】:

          猜你喜欢
          • 2013-06-26
          • 2011-07-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-28
          • 2020-09-07
          • 2019-09-02
          • 2016-01-22
          相关资源
          最近更新 更多