Как сделать LEFT OUTER JOIN без внешнего ключа с помощью django orm

У меня есть следующие модели:

class User(Model):
    ### 
    user fields
    ###

class CaseModel(Model):
    id = # django build in id field
    owner = models.ForeignKey('User')
    ### 
    other fields
    ###


class DraftMessageModel(Model):
    entity_id = models.IntegerField(null=True, blank=True) # CaseModel.id is linked to this
    ### 
    other fields
    ###

Мне нужно построить queryset, который генерирует следующий SQL:

SELECT 
  C.id, 
  C.some_field, 
  D.another_field, 
  U.username,
  < some extra fields > 
FROM 
  CaseModel AS C 
  LEFT OUTER JOIN User AS U ON (C.owner_id = U.id) 
  LEFT OUTER JOIN DraftMessageModel AS D ON (C.id = D.entity_id) 
WHERE 
  C.owner_id = 100 
  AND < some extra condition >

Я знаю, что это банальный вопрос, но я не смог справиться с ним queryset.extra или queryset.annotate(draft_message=FilteredRelation()).

Вот что я пробовал до сих пор:

  • queryset.annotate
queryset = CaseModel.objects.select_related('owner').filter(owner_id=100)

queryset = queryset.annotate(
    draft_message=FilteredRelation(
        'draftmessagemodel',
        condition=Q(draftmessagemodel__entity_id=F('id'))
    )
)
# error: Cannot resolve keyword 'draftmessagemodel' into field. Choices are: <CaseModel's other fields>
  • queryset.extra
queryset = CaseModel.objects.select_related('owner').filter(owner_id=100)

queryset = queryset.extra(
    select={
        'draftmessagemodel__id': 'draftmessagemodel.id',
        'draftmessagemodel__text': 'draftmessagemodel.text',
    },
    tables=['draftmessagemodel'],
    where=[
        'casemodel.id = draftmessagemodel.entity_id'
    ]
)

генерирование нежелательного sql:

SELECT 
  "casemodel"."id", 
  "user"."username",
  (draftmessagemodel.id) AS "draftmessagemodel__id", 
  (draftmessagemodel.text) AS "draftmessagemodel__text",
  <some other fields>
  
FROM 
  "casemodel" 
  LEFT OUTER JOIN "user" ON (
    "casemodel"."owner_id" = "user"."id"
  ), -- I didn't unserstand from where this comma come here
  "draftmessagemodel" 
WHERE 
  (
    "casemodel"."owner_id" = 100 
    AND (
      casemodel.id = draftmessagemodel.entity_id
    )
  )

Здравствуйте. Я пользователь Django из Кореи.

Я не знаю. что именно вы хотите (потому что вы предоставили только частичную информацию), но вы можете примерно действовать следующим образом.

a = DraftMessageModel.objects.get({filter})
b = User.objects.get({filter})
CaseModel.objects.only('id', 'username', 'draftmessagemodel_id').filter(owner_id=100, id=a.entity_id, owner_id=b.id).annotate(draftmessagemodel__text='draftmessagemodel__text')
Вернуться на верх