Полное внешнее соединение в django

Как я могу создать запрос для полного внешнего соединения через чип отношений M2M, используя django QuerySet API?

Это не поддерживается, хотелось бы получить некоторые подсказки о создании моего собственного менеджера для этого.

Отредактировано для добавления: @ С.Лотт: Спасибо за просветление. Потребность во ВНЕШНЕМ СОЕДИНЕНИИ исходит из приложения. Он должен создать отчет, показывающий введенные данные, даже если они все еще не полны. Я не знал, что в результате получится новый класс / модель. Ваши подсказки мне немного помогут.

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
11
0
13 562
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Django не поддерживает «объединения» в обычном смысле SQL - он поддерживает навигацию по объектам.

Обратите внимание, что реляционное соединение (внутреннее или внешнее) создает новый «класс» сущностей. Тот, который не имеет определения в Django. Таким образом, нет правильного «набора результатов», поскольку нет определения класса для вещей, которые вы получаете обратно. Лучшее, что вы можете сделать, - это определить кортеж, который будет содержать None для отсутствующих комбинаций.

Левое (или правое) внешнее соединение выглядит так. Он создает два непересекающихся подмножества: те, у которых есть связанный набор связанных сущностей, и те, у которых нет.

for obj in Model1.objects.all():
    if obj.model2_set().count() == 0:
        # process (obj, None) -- no Model2 association
    else:
        for obj2 in obj.model2_set.all():
            # process (obj, obj2) -- the "inner join" result

«Полное» внешнее соединение - это объединение оставшихся элементов, не связанных между собой.

for obj2 in Model2.objects.all():
    if obj2.model1_set().count() == 0:
        # process (None, obj2) -- no Model1 association

Вопрос всегда в том, какую обработку вы делаете с этой странной коллекцией из трех разных подмножеств объектов?

Задача объектной базы данных - сосредоточить обработку на объекте и связанных с ним объектах.

Своеобразная коллекция, называемая «реляционным соединением», никогда не присутствует в исходной объектной модели. Это новый класс объектов, созданный из двух (или более) исходных объектов.

Хуже того, внешние соединения создают коллекцию с несколькими подклассами (внутреннее соединение, левое внешнее соединение и правое внешнее соединение). Что значит этот сборник вещей иметь в виду?

Подожди, может стать хуже. Если обработка включает проверку отсутствующих атрибутов (например, if someObj.anObj2attribute is None: мы, по сути, ищем элементы Model1, не связанные с объектом Model2. Эммм ... почему мы поместили их во внешнее соединение, только чтобы отфильтровать их с помощью оператора if? Почему бы просто не выполнять отдельные запросы и правильно обрабатывать каждое подмножество?


Обновлено: когда вы показываете «незавершенный» статус, это вообще не внешнее соединение. Все намного проще. Вам необходимо создать одну (или две) отдельные коллекции в вашей функции просмотра для отображения вашего шаблона.

Во-первых, вы должны использовать коды состояния, а не наличие или отсутствие внешнего ключа. Необязательные внешние ключи не имеют «причин» - они либо есть, либо нет. Код состояния может давать полезные оттенки значения («неполный», «ошибочно», «сломанный», «неприменимо», «подлежит удалению» и т. д.)

errorList1 = Model1.objects.filter( status = "Incomplete" )
errorList2 = Model2.objects.filter( status = "Incomplete" )

Эти две части являются двумя несоединяемыми частями полного внешнего соединения. Затем вы можете отобразить эти два списка ошибок в своем шаблоне с соответствующими заголовками столбцов, кодами состояния и всем остальным.

Вы даже можете поместить их в одну таблицу, чтобы имитировать старый отчет о полном внешнем соединении, который люди привыкли видеть.

<table>
    <tr><th>Model1</th><th>Model2</th></tr>
    {% for e1 in errorList1 %}
    <tr><td>e1</td><td>NULL</td></tr>
    {% endfor %}
    {% for e2 in errorList2 %}
    <tr><td>NULL</td><td>e2</td></tr>
    {% endfor %}
</table>

Похоже на полный отчет о внешнем соединении. Без полного внешнего соединения.

Ты прав. Я напишу представление, которое вычисляет необходимую таблицу для моего «ПОЛНОГО ВНЕШНЕГО СОЕДИНЕНИЯ» в python, а затем передает результат в шаблон для рендеринга. Спасибо.

Ber 31.10.2008 18:05

Я смотрю на это и нахожу интересным, что, поскольку мы находимся на переходе к другой архитектуре, у нас действительно есть вариант использования для этого, и мы получаем результаты, которые ограничиваются любой архитектурой и теми, которые являются точками данных, которые в настоящее время существуют в обеих. Поэтому то, что вы не стали бы спроектировать его таким образом с нуля, не означает, что варианты использования не встречаются в реальной жизни.

NeilG 06.03.2020 07:56

Колин, один из парней, с которыми я работаю, недавно написал сообщение о пользовательских соединениях в Django:

http://www.caktusgroup.com/blog/2009/09/28/custom-joins-with-djangos-queryjoin/

Возможно, вы найдете там что-нибудь полезное!

Другие вопросы по теме