Форум сайта python.su
EvgIqПример кода и описание эксепшена, которое говорит, что нельзя.
Просто интересно - какой ответ вы ожидаете?
EvgIqС точки зрения реляционной теории - промежуточная таблица единственно верный способ реализации M2M связи данных. И то что вы описали с PersonInGroup абсолютно тоже самое что делать джанга автоматичнски обрабатывая ManyToManyField. Так что, чем ваше “по старинке” отличается от стандартного поведения не понятно:-) through лишь позволяет задать в место автоматически сгенерированной - свою модель.
Конечно кому-то это может и нравится, но я предпочитаю “по старинке”
Т.е. Есть таблица - Persons, и таблица - Groups. Так же есть таблица PersonInGroup которая содержит ключи из Persons и Groups. Так же в нее вы можете включить и всю другую инфу о Person (когда он в нее вошел, какой у него в ней статус и т.п. и т.д)
Офлайн
krasulyaВ документации говорится конкретно про ManyToManyField. Но если говорить про M2M отношение как таковое, то никто не мешает вам отказаться от этого поля, cделав Friendship модель с двумя ссылками на Person, и обращаться к ней напрямую.
Об этом говорится в документации. А первопричину назвать, к сожалению, не могу.
Офлайн
Я имел ввиду реализацию без поля ManyToMany. Т.е. вручную создать 3-ю таблицу. В смысле получаемого результата в структуре БД - разницы нет. Я и не утверждал, что она есть.
Понятно, что ORM Django пытается “упростить” создание и работу с отношением данного вида, но мне (лично мне, другим - не знаю) это кажется лишним, т.к. никакой практической пользы от этого нет, а путаницу (особенно тем кто не знаком с теорией реляционных БД) данное “упрощение” привносит.
Отредактировано (Янв. 11, 2010 06:05:03)
Офлайн
2EvgIq
Я говорю о связи таблицы к самой себе (self). Я хочу понять как пожно реализовать подобную связь используя для связи какой-то класс. Со связью между разными таблицами проблем нет.
Можно увидеть рабочий пример того, о чем вы говорите?
Офлайн
Я может чего-то не понял, прошу прощения.
Вам зачем связь “самой таблицы к себе”? Мне она бывает нужна только в одном случае - для организации структуры “дерева” (я имею ввиду ограничение по ForeignKey). А уж связь ManyToMany самой таблицы к себе, я, если честно, не представляю зачем может понадобиться (кстати при явном объявлении такого поля - Django тоже у вас ругается, значит я не одинок :)).
Если вам необходим механизм группировки пользователей (например для создания группы “Друзья”, которая с точки зрения БД, ничем не отличается от, например, группы “сослуживцы” или “враги” :)), то достаточно создать 2 таблицы - Персоны и Группы, а так же 3-ю таблицу в которой прописано отношение между первыми двумя.
Если вы планируете группировать Персоны только по одной группе “Друзья”,и точно уверенны, что больше групп не будет, тогда надо только 2 таблицы - Персоны и Друзья. Где в таблице друзья будет 2-а поля с id из таблицы Персоны (ключи друзей) и другие поля, которые вам будут необходимы для уточнения истории, статуса и т.д и т.п. дружеских отношений. Только я бы и в этом случае выбрал 1-й вариант реализации.
Рабочие примеры кода работы с таблицами по ограничению ForeignKey и даже ManyToMany есть на djbook.ru
Группы, так сказать, в действии - на любом социальном (и не только) сайте :)
Офлайн
EvgIq, вы, наверно, на самом деле немного меня не поняли.
Я говорю не об отдельной группе друзья. Пример с персонами и группами я привел только для того, чтобы продемонстрировать, что я хочу от связи self many-to-many. Мне нужно реализовать “механизм дружбы” как в соцсетях. Т.е. пользователь сайта может добавить другого пользователя себе в друзья. И эта связь является двусторонней. Т.е. если пользователь добавил пользователь1 добавил пользователя2 в друзья, то в друзьях пользователя2 автоматически появляется пользователь1.
Офлайн
Это можно (а я думаю и нужно) реализовать описанным мною способом. В таблице, описывающей отношение ManyToMany есть 2 поля с ID персон. Например, таблица Друзья может выглядеть так:
(поля: id_person1, id_person2, date_create, prim, status) (состояние на 11.01.2010 :) )
1, 2, 01.01.2010, “с похмелья полез в инет, увидел друга с id_person=2, добавил его в свои Друзья”,True
1, 3, 08.01.2010, “с похмелья опять полез в инет, увидел друга с id_person=3, добавил его в свои Друзья”,False
2, 1, 11.01.2010, “пришел на работу, увидел, что id_person=1, напрашивается в Друзья, подумал, согласился, будет с кем бухнуть 13-го”,True
3, 1, 11.01.2010, “пришел на работу, увидел, что id_person=1, напрашивается в Друзья, подумал, а ну его, пьет много”,False
:)
Отредактировано (Янв. 11, 2010 16:01:29)
Офлайн
EvgIqКак не странно это может понадобиться в ситуации которую описал топик стартер. И уже, наверно, не поверите вы, но сделать M2M на себя можно. Но как уже отметил топикстартер этого нельзя сделать через явно заданную through таблицу.
А уж связь ManyToMany самой таблицы к себе, я, если честно, не представляю зачем может понадобиться (кстати при явном объявлении такого поля - Django тоже у вас ругается, значит я не одинок smile).
class Friendship(models.Model):
who = models.ForeignKey(Person, related_name='whom_friendships')
with_whom = models.ForeignKey(Person, relate_name='with_whom_friendships')
# тут любые другие нужные поля
EvgIqВот именно тоже самое делает M2M('self').
Если вы планируете группировать Персоны только по одной группе “Друзья”,и точно уверенны, что больше групп не будет, тогда надо только 2 таблицы - Персоны и Друзья. Где в таблице друзья будет 2-а поля с id из таблицы Персоны (ключи друзей) и другие поля, которые вам будут необходимы для уточнения истории, статуса и т.д и т.п. дружеских отношений.
EvgIqТогда лишним должна стать вся Джанга потому что она есть по сути сахар вокруг WSGI интерфейса, логики обработки запроса и ввода/вывода данных. Но как вы понимаете это и есть её цель – упрощение. А значит глупо отказываться от удобств, которые она предоставляет.
Понятно, что ORM Django пытается “упростить” создание и работу с отношением данного вида, но мне (лично мне, другим - не знаю) это кажется лишним
Офлайн
Заранее извиняюсь перед krasulya, в следующих буквах не ничего ценного по теме…
Уважаемый Daevaorn.
Странный у Вас подход, я бы даже сказал - не последовательный.
Вы пишете
Но как уже отметил топикстартер этого нельзя сделать через явно заданную through таблицу.теперь мои слова насчет “одиночества” :)
(кстати при явном объявлении такого поля - Django тоже у вас ругается, значит я не одинок smile).теперь Ваш PS
PS: одиноки:-) к счастью.Что-то, наверное, я не понимаю. Или затронул-обидел Вас чем-то (В своем первом ответе в этой теме:“…Просто интересно - какой ответ вы ожидаете?…”. Но мне правда интересно было, я не стал тогда обсуждать Ваш ответ-“отписку” т.к. топикстартер сам ответил, где искать ответ на ошибку), извините не хотел, но в любом случае рад, что кого-то осчастливил, хоть и не пойму чем.
трудные пути решения легких для Джанги задачТем более, что Вы после нелогичной критики сами же пишите:
Вот именно тоже самое делат M2M('self').В ваших ответах конструктива, по моему, гораздо меньше.
Офлайн
хотя ответ спустя 2 года =), но для будущих поколений =)
тут подробнее
class Contact(models.Model): contacts = models.ManyToManyField( 'self', through='ContactRelationship', symmetrical=False, ) class ContactRelationship(models.Model): types = models.ManyToManyField( 'RelationshipType', related_name='contact_relationships', blank=True, ) from_contact = models.ForeignKey('Contact', related_name='from_contacts') to_contact = models.ForeignKey('Contact', related_name='to_contacts') class Meta: unique_together = ('from_contact', 'to_contact')
Офлайн