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


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>
Похоже на полный отчет о внешнем соединении. Без полного внешнего соединения.
Я смотрю на это и нахожу интересным, что, поскольку мы находимся на переходе к другой архитектуре, у нас действительно есть вариант использования для этого, и мы получаем результаты, которые ограничиваются любой архитектурой и теми, которые являются точками данных, которые в настоящее время существуют в обеих. Поэтому то, что вы не стали бы спроектировать его таким образом с нуля, не означает, что варианты использования не встречаются в реальной жизни.
Колин, один из парней, с которыми я работаю, недавно написал сообщение о пользовательских соединениях в Django:
http://www.caktusgroup.com/blog/2009/09/28/custom-joins-with-djangos-queryjoin/
Возможно, вы найдете там что-нибудь полезное!
Ты прав. Я напишу представление, которое вычисляет необходимую таблицу для моего «ПОЛНОГО ВНЕШНЕГО СОЕДИНЕНИЯ» в python, а затем передает результат в шаблон для рендеринга. Спасибо.