Термин ORDER BY не соответствует ни одному столбцу в наборе результатов
Вы получаете эту ошибку, потому что это именно то, что происходит. Ваш окончательный набор результатов для статей не содержит столбца хитов из таблицы HitCount , из-за которого набор результатов не может заказать с использованием этого столбца.
Доуглубившись в ответ, давайте посмотрим, что происходит с вашими наборами запросов django под капотом.
Извлечение определенного набора статей и добавление дополнительного поля заказа qs_order, установленного в 0.
articles_by_id = Article.objects.filter(id__in=ids).annotate(qs_order=models.Value(0, models.IntegerField()))
SQL-запрос для вышеупомянутого
Select id, title,....., 0 as qs_order from article where article.id in (Select ....) # whatever you did to get your ids or just a flat list
Получить другой набор статей и включить дополнительное поле заказа qs_order, установленное в 1
articles_by_name = Article.objects.filter(title__icontains='sports').annotate(qs_order=models.Value(1, models.IntegerField()))
SQL-запрос для вышеуказанного
Select id, title, ...1 as qs_order from article where title ilike '%sports%'
Исходный набор запросов и order_by hit_count_generic__hits
Article.objects.order_by('hit_count_generic__hits')
Это фактически выполнитвнутреннее объединение и выборка таблицы счетчиков обращений по столбцам обращений.
Запрос
Select id, title,... from article inner join hitcount on ... order by hits ASC
Объединение
Таким образом, когда вы делаете ваш союз, набор результатов из вышеупомянутых 2 запросов объединяетсяи затем заказал, используя ваш qs_order , а затем ударил ... там, где это не удалось.
Решение
Используйте prefetch_related toполучите свою таблицу количества посещений в начальной фильтрации наборов запросов, чтобы затем использовать столбец совпадений в объединении для упорядочения.
articles_by_id = Article.objects.prefetch_related('hit_count_generic').filter(id__in=ids).annotate(qs_order=models.Value(0, models.IntegerField()))
articles_by_name = Article.objects.prefetch_related('hit_count_generic').filter(title__icontains='sports').annotate(qs_order=models.Value(1, models.IntegerField()))
Теперь, когда у вас есть нужная таблица и ее столбцы в обоих запросах SELECT, вашunion должен работать так, как вы определили.
articles = articles_by_id.union(articles_by_name).order_by('qs_order', 'hit_count_generic__hits')