Как создать объединение двух разных django-моделей? - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть две django-модели

class ModelA(models.Model):
    title = models.CharField(..., db_column='title')
    text_a = models.CharField(..., db_column='text_a')
    other_column = models.CharField(/*...*/ db_column='other_column_a')


class ModelB(models.Model):
    title = models.CharField(..., db_column='title')
    text_a = models.CharField(..., db_column='text_b')
    other_column = None 

Затем я хочу объединить два набора запросов этих моделей, используя union

ModelA.objects.all().union(ModelB.objects.all())

Но в запросе я вижу

(SELECT
`model_a`.`title`,
`model_a`.`text_a`,
`model_a`.`other_column`
FROM `model_a`)

UNION
(SELECT
`model_b`.`title`,
`model_b`.`text_b`
FROM `model_b`)

Конечно, я получил исключение The used SELECT statements have a different number of columns.

Как создать псевдонимы и поддельные столбцы для использования union-запроса?

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

В Django операции объединения должны иметь одинаковые столбцы, поэтому с values_list вы можете использовать эти конкретные столбцы только так:

qsa = ModelA.objects.all().values('text_a', 'title')
qsb = ModelB.objects.all().values('text_a', 'title')

qsa.union(qsb)

Но я не знаю (о чем я знаю)подражать NULL в союзе в Джанго.Таким образом, вы можете продолжить работу двумя способами.

Первый: добавьте дополнительное поле в вашу модель с именем other_column.Вы можете оставить значения пустыми, например:

other_column = models.CharField(max_length=255, null=True, default=None)

и использовать операции объединения наборов запросов Django, как описано в здесь .

Last One, подход является немного питоническим,Попробуйте вот так:

a = ModelA.objects.values_list('text_a', 'title', 'other_column')
b = ModelB.objects.values_list('text_a', 'title')

union_list = list()

for i in range(0, len(a)):
     if b[i] not in a[i]:
         union_list.append(b[i])
     union_list.append(a[i])

Надеюсь, это поможет !!

0 голосов
/ 27 ноября 2018

В запросе SQL мы можем использовать NULL для определения оставшихся столбцов / псевдонимов

(SELECT
`model_a`.`title`,
`model_a`.`text_a`,
`model_a`.`other_column`
 FROM `model_a`)

UNION

(SELECT
`model_b`.`title`,
`model_b`.`text_b`, 
 NULL
 FROM `model_b`)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...