Django ORM: возможно ли аннотировать QuerySet полем через обычное и обратное отношение внешнего ключа?
Предположим следующие классы моделей:
class Person(models.Model):
# ...irrelevant fields...
class PersonEmailLogin(AbstractBaseUser):
email = models.EmailField()
person = models.ForeignKey(Person)
# ...more irrelevant fields...
class SomeModel(models.Model):
person = models.ForeignKey(Person)
# ...more irrelevant fields...
Примечание: это все неуправляемые модели - мы разрабатываем на основе существующей базы данных, которая не управляется нами.
Хотя это не выражено в приведенном выше коде, вне Django гарантируется, что для каждого Person, 0-1 PersonEmailLogin будут указывать на него.
Я хочу получить SomeModel объектов, но аннотировать каждую строку полем email из PersonEmailLogin. Это должно быть сделано с помощью внешнего соединения, поскольку не все Person имеют PersonEmailLogins.
SomeModel не имеет прямого внешнего ключа к PersonEmailLogin, но поскольку они оба указывают на Person, можно связать экземпляр SomeModel с одним экземпляром PersonEmailLogin, или NULL, когда данный Person не имеет ни одного PersonEmailLogin, указывающего на него.
При использовании SomeModel.objects.raw() текущий запрос выглядит следующим образом:
SELECT sm.*, pel.email FROM somemodel sm
LEFT OUTER JOIN personemaillogin pel ON sm.person_id = pel.person_id;
Я бы предпочел использовать обычные QuerySets вместо RawQuerySets, так как было бы удобнее выполнять больше операций фильтрации, но я не нашел способа выразить этот запрос. Можно ли это сделать с помощью Django ORM, не прибегая к подзапросам (медленным в нашем случае)? Объекты FilteredRelation могут быть использованы для принудительных внешних объединений, но я не вижу, как они будут работать в данном случае.