Как создать объект django queryset для внутреннего соединения?

У меня есть две таблицы.

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'

Каким будет эквивалентный запрос django для внутреннего соединения двух таблиц по столбцу nsn? Моя функция представления будет иметь вид

def inner(request,nsn):
    obj = .......................
    context = {'obj':obj}
    return render(request,,"a.html",context)

queryset должен возвращать комбинацию двух таблиц в соответствии с общим nsn.

Вариант №1 - Внедрение внешнего ключа (рекомендуется):

В класс DibbsSpiderDibbsMatchedProductFieldsDuplicate добавить:

fkey = models.ForeignKey('DibbsSpiderSolicitation')

тогда вы можете легко получить доступ к их присоединению:

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

Теперь это ваш выбор, что вы хотите сделать с nsn2

Вариант №2 - без ForeigKey:

Raw 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)

Простите, я не смог протестировать ни одного.

Вы можете попробовать некоторые из вариантов:

  1. Добавление ограничения внешнего ключа и использование select_related в соответствии с этим постом
  2. .
  3. Сырой запрос, как указано в этом посте stackoverflow и другом посте с пользовательскими объединениями

3. Использование запроса IN в соответствии со следующей логикой:

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

Во-первых, отличные названия моделей. Давайте сделаем их псевдонимами: 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

Вернуться на верх