Feature request: make it possible to "tell" filter that would result a join, to add an additional condition to that join

48 views
Skip to first unread message

Delusional Insanity

unread,
Apr 21, 2015, 11:05:13 AM4/21/15
to django-d...@googlegroups.com
Feature request: make it possible to "tell" filter that would result a join, to add an additional condition to that join

Consider the following models:

Country:
   name # CharField
   slug # SlugField

Topic:
   name # CharField
   slug # SlugField

Project:
   name # CharField
   slug # SlugField
   topic = ForeignKey(Topic)
   budget # IntegerField

ProjectLocation
    project = ForeignKey(Project)
    country = ForeignKey(Country)
    latitude # DecimalField
    longitude # DecimalField

I want to calculate total amounts per country for projects that are located in certain countries.

If I do so, finally filtering on Country.slug, I also get totals for countries that aren't in the selection.

The produced query is similar to the following:

    SELECT DISTINCT `website_country`.`name`, 
                    `website_country`.`slug`, 
                    SUM(`website_project`.`budget`) AS `total_budget` 
    FROM `website_project` 
    LEFT OUTER JOIN `website_projectlocation` 
        ON (`website_project`.`id` = `website_projectlocation`.`project_id`) 
    LEFT OUTER JOIN `website_country` 
        ON (`website_projectlocation`.`country_id` = `website_country`.`id`) 
    INNER JOIN `website_topic` 
        ON (`website_project`.`topic_id` = `website_topic`.`id`) 
    INNER JOIN `website_projectlocation` T7 
        ON (`website_project`.`id` = T7.`project_id`) 
    INNER JOIN `website_country` T8 
        ON (T7.`country_id` = T8.`id`) 
    WHERE (`website_topict`.`slug` IN ("child-education") AND 
           T8.`iso2` IN ("MY", "BI", "MW")) 
    GROUP BY `website_country`.`name`, `website_country`.`slug` 
    ORDER BY NULL

When I change the query to the following it works as needed:

    SELECT DISTINCT `website_country`.`name`, 
                    `website_country`.`slug`, 
                    SUM(`website_project`.`budget`) AS `total_budget` 
    FROM `website_project` 
    LEFT OUTER JOIN `website_projectlocation` 
        ON (`website_project`.`id` = `website_projectlocation`.`project_id`) 
    LEFT OUTER JOIN `website_country` 
        ON (`website_projectlocation`.`country_id` = `website_country`.`id` AND `website_country`.`iso2` IN ("MY", "BI", "MW")) 
    INNER JOIN `website_topic` 
        ON (`website_project`.`topic_id` = `website_topic`.`id`) 
    INNER JOIN `website_projectlocation` T7 
        ON (`website_project`.`id` = T7.`project_id`) 
    INNER JOIN `website_country` T8 
        ON (T7.`country_id` = T8.`id`) 
    WHERE (`website_topict`.`slug` IN ("child-education") AND 
           T8.`iso2` IN ("MY", "BI", "MW")) 
    GROUP BY `website_country`.`name`, `website_country`.`slug` 
    ORDER BY NULL

Thus, it would be great to be able to tell somewhere in the filtering that certain filter should be applied also as additional statement for the appropriate JOIN.

For example, instead of:

    Project.filter(projectlocation__country__slug__in=['MY', 'BI', 'MW'])

the following

    Project.filter(projectlocation__country__slug__in=['MY', 'BI', 'MW'], use_in_joins=True)

Reply all
Reply to author
Forward
0 new messages