class QLeftOuterJoin(models.Q):
    """
        Example:
        [alias, table to join, field, table, field]
        QLeftOuterJoin('mm_p', Post, 'pk', Category, 'last_post')
        
        class Thread(models.Model):
            category = models.ForeignKey(Category)
            subject = models.CharField(_('subject'), maxlength=255)
            last_post = models.ForeignKey("Post", editable=False, null=True, blank=True, default=None)
        
        class Post(models.Model):
            thread = models.ForeignKey(Thread, verbose_name=_('thread'))
            writer = models.ForeignKey(User, verbose_name=_('writer'), editable=False, null=True, blank=True)
            writer_verbose_name = models.CharField(_("writer's verbose name"), maxlength=255, editable=False)
            content = models.TextField(_('content'))
            created = models.DateTimeField(_('created'), editable=False)
            modified = models.DateTimeField(_('modified'), editable=False)
        
        threads = Thread.items.filter(
            Q(category=1) &
            QLeftOuterJoin('thread_last_post', Post, 'pk', Thread, 'last_post')
            ).select_related().extra(select={
                'last_post_modified': '`thread_last_post`.`modified`',
            })
    """
    def __init__(self, alias, table1, field1, table2, field2):
        if isinstance(table1, models.base.ModelBase):
            if field1 is None or field1 == 'pk':
                field1 = table1._meta.pk.name
            try:
                field1 = table1._meta.get_field(field1).column
            except AttributeError, e:
                raise AttributeError, "%s: %s" % (e, "table: %s, field: %s" % table1, field1)
            table1 = table1._meta.db_table            
        
        if isinstance(table2, models.base.ModelBase):
            if field2 is None or field2 == 'pk':
                field2 = table2._meta.pk.name
            try:
                field2 = table2._meta.get_field(field2).column
            except AttributeError, e:
                raise AttributeError, "%s: %s" % (e, "table: %s, field: %s" % table1, field1)
            table2 = table2._meta.db_table
        
        self.where = "%s.%s = %s.%s" % (alias, field1, table2, field2)
        self.alias, self.table = alias, table1
        
    def get_sql(self, opts):
        joins = SortedDict()
        joins[self.alias] = (self.table, 'LEFT OUTER JOIN', self.where)
        return (joins, [], [])