It would be nice if there was some database level optimization for getting
objects that have related objects that exist.

This is a slow filter:

qs = [obj for obj in qs if qs.somefield_set.exists()]

Could be faster with something like this:

qs = qs.filter(somefield__exists=True)

Here is some (rough, probably grossly over simplified but working) code:

Code is also available here if it gets garbled: http://dpaste.com/0825PNP


query_template = (
        '{not_part} EXISTS (SELECT 1 FROM "{table1}" WHERE '
        '"{table1}"."{table1_column}" = "{table2}"."{table2_column}")'
)
def filter_by_reverse_feriegn_key_existance(qs, **kw):

        for arg, value in kw.items():

                assert arg.endswith('__exists')

                if value is True:
                        not_part = ''
                elif value is False:
                        not_part = 'NOT'

                Model = qs.model
                for field in arg.rstrip('__exists').split('__'):
                        field = Model._meta.get_field_by_name(field)[0]

                        qs = qs.extra(where=[query_template.format(
                                table1=field.model._meta.db_table,
                                table1_column=field.field.db_column,
                                table2=Model._meta.db_table,
                                table2_column=Model._meta.pk.db_column,
                                not_part = not_part
                        )])

                        Model = field.model
        return qs


This works on postgres, and is ~100x faster

I would be interested in any comments

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CANm61jfR9ZTktKGB-e5KFC%3D0rQ_%3Db0xN%3Dgm6PxMv%3D0ZYKOKwPQ%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to