Django Custom Left Outer Join

I have a Django model request with this

news = News.objects.filter(Q(likes__user__isnull=True)|Q(likes__user=user))
.extra(select={"is_liked":NewsLikes._meta.db_table+".user_id = %d" % user.id})

which gives me the following request

SELECT (shows_newslikes.user_id = 143) AS `is_liked`, * FROM `shows_news` 
LEFT OUTER JOIN `shows_newslikes` ON ( `shows_news`.`id` = `shows_newslikes`.`news_id`)
WHERE (`shows_newslikes`.`user_id` IS NULL OR `shows_newslikes`.`user_id` = 143 )

what i want is the following query as result

SELECT (shows_newslikes.user_id = 143) AS `is_liked`, * 
FROM `shows_news` LEFT OUTER JOIN `shows_newslikes` ON ( `shows_news`.`id` = 
`shows_newslikes`.`news_id` and `shows_newslikes`.`user_id` = 143 ) WHERE 
(`shows_newslikes`.`user_id` IS NULL  )

So what I need to do in a Django model request

+4
source share
1 answer

It is difficult to generate this form LEFT OUTER JOINwithout using raw(); You also need to distinct()duplicate rows. I would use EXISTSone that would be cleaner and most likely faster:

news = News.objects.extra(select={'is_liked':
    'EXISTS (SELECT 1 FROM {tbl_2} '
    'WHERE {tbl_2}.news_id = {tbl}.id AND {tbl_2}.user_id = %s)'.format(
        tbl=News._meta.db_table,
        tbl_2=NewsLikes._meta.dbtable)}, select_params=(user.id,))
+3
source

All Articles