• Как в Django ORM сделать несколько join к одной и той же таблице?

    @gimntut
    Если использовать много join, то запрос становится медленным. Гораздо быстрее работают подзапросы, особенно в сочетании с пагинацией.
    Goods.objects.annotate(
        PriceGroups_id_1_price = Subquery(Price.objects.filter(goods_id=OuterRef('id'), pricegroup_id=1).values('price')[:1]),
        PriceGroups_id_2_price = Subquery(Price.objects.filter(goods_id=OuterRef('id'), pricegroup_id=2).values('price')[:1]),
        PriceGroups_id_3_price = Subquery(Price.objects.filter(goods_id=OuterRef('id'), pricegroup_id=3).values('price')[:1]),
    )


    В целом архитектура БД кажется странной, т.к. если групп всего и всегда три, то лучше цены хранить в отдельных полях модели Goods.
    Если количество групп меняется, то кроме проблемы с которой уже столкнулись, будет ещё множество проблем и не факт, что можно будет найти их решение.

    То же самое решение, но для переменного числа групп:
    group_count = 3
    subquery = Subquery(Price.objects.filter(goods_id=OuterRef('id')))
    qs = Goods.objects.annotate(
        **{
            f'PriceGroups_id_{group_id}_price': subquery.filter(pricegroup_id=group_id).values(
                'price')[:1]
            for group_id in range(1, group_count + 1)
        }
    )
    Ответ написан
    Комментировать