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
имеют PersonEmailLogin
s.
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
могут быть использованы для принудительных внешних объединений, но я не вижу, как они будут работать в данном случае.