Complex DB query fun

42 views
Skip to first unread message

Samuel Smith

unread,
Feb 6, 2021, 6:42:32 PM2/6/21
to django...@googlegroups.com
I have a blog that is using django-taggit and on my list and detail
views, I'd like to have a section to display other posts with related
tags. At first I thought I could just use a correlated sub-select with
annotate() along with the postgresql string_agg() to squeeze the related
blog post's title and tag list into one column, but then realized that
I'd still have the issue of returning multiple rows. I could put another
select with string_agg around that but figured there must be a better way..

So I played with just using joins and came up with:


select b.title, r.*
from blog_post b
left join lateral (
select
bp.id as id, bp.title as related_title, bp.slug as related_slug,
string_agg(tt.name,', ') as related_tags, count(*) as related_count
from blog_post bp
inner join taggit_taggeditem tti on tti.object_id = bp.id
inner join taggit_tag tt on tt.id = tti.tag_id
where tt.id in ( select tag_id from taggit_taggeditem tt3 where
tt3.object_id = b.id ) and bp.id != b.id
group by bp.title,bp.slug, bp.id
having count(*) > 1
limit 4
) as r on 1 = 1
order by b.title, r.related_count desc

So that gives me a list of all blog posts joined with a list of their
top 4 other related posts including a related tag list and count.

So how to shove that into django? Should I try something with annotate
and rawsql() or would it be better to just create this query as a
database view and make an unmanaged model to join to?

Regards,
Samuel Smith

Reply all
Reply to author
Forward
0 new messages