Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 10, 2010 22:52:29

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

self many-to-many through

EvgIq
Просто интересно - какой ответ вы ожидаете?
Пример кода и описание эксепшена, которое говорит, что нельзя.
EvgIq
Конечно кому-то это может и нравится, но я предпочитаю “по старинке”
Т.е. Есть таблица - Persons, и таблица - Groups. Так же есть таблица PersonInGroup которая содержит ключи из Persons и Groups. Так же в нее вы можете включить и всю другую инфу о Person (когда он в нее вошел, какой у него в ней статус и т.п. и т.д)
С точки зрения реляционной теории - промежуточная таблица единственно верный способ реализации M2M связи данных. И то что вы описали с PersonInGroup абсолютно тоже самое что делать джанга автоматичнски обрабатывая ManyToManyField. Так что, чем ваше “по старинке” отличается от стандартного поведения не понятно:-) through лишь позволяет задать в место автоматически сгенерированной - свою модель.



Офлайн

#2 Янв. 10, 2010 22:57:00

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

self many-to-many through

krasulya
Об этом говорится в документации. А первопричину назвать, к сожалению, не могу.
В документации говорится конкретно про ManyToManyField. Но если говорить про M2M отношение как таковое, то никто не мешает вам отказаться от этого поля, cделав Friendship модель с двумя ссылками на Person, и обращаться к ней напрямую.



Офлайн

#3 Янв. 10, 2010 23:05:26

EvgIq
От:
Зарегистрирован: 2009-11-14
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

self many-to-many through

Я имел ввиду реализацию без поля ManyToMany. Т.е. вручную создать 3-ю таблицу. В смысле получаемого результата в структуре БД - разницы нет. Я и не утверждал, что она есть.
Понятно, что ORM Django пытается “упростить” создание и работу с отношением данного вида, но мне (лично мне, другим - не знаю) это кажется лишним, т.к. никакой практической пользы от этого нет, а путаницу (особенно тем кто не знаком с теорией реляционных БД) данное “упрощение” привносит.



Отредактировано (Янв. 11, 2010 06:05:03)

Офлайн

#4 Янв. 11, 2010 09:28:49

krasulya
От:
Зарегистрирован: 2010-01-09
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

self many-to-many through

2EvgIq

Я говорю о связи таблицы к самой себе (self). Я хочу понять как пожно реализовать подобную связь используя для связи какой-то класс. Со связью между разными таблицами проблем нет.

Можно увидеть рабочий пример того, о чем вы говорите?



Офлайн

#5 Янв. 11, 2010 14:09:31

EvgIq
От:
Зарегистрирован: 2009-11-14
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

self many-to-many through

Я может чего-то не понял, прошу прощения.
Вам зачем связь “самой таблицы к себе”? Мне она бывает нужна только в одном случае - для организации структуры “дерева” (я имею ввиду ограничение по ForeignKey). А уж связь ManyToMany самой таблицы к себе, я, если честно, не представляю зачем может понадобиться (кстати при явном объявлении такого поля - Django тоже у вас ругается, значит я не одинок :)).

Если вам необходим механизм группировки пользователей (например для создания группы “Друзья”, которая с точки зрения БД, ничем не отличается от, например, группы “сослуживцы” или “враги” :)), то достаточно создать 2 таблицы - Персоны и Группы, а так же 3-ю таблицу в которой прописано отношение между первыми двумя.

Если вы планируете группировать Персоны только по одной группе “Друзья”,и точно уверенны, что больше групп не будет, тогда надо только 2 таблицы - Персоны и Друзья. Где в таблице друзья будет 2-а поля с id из таблицы Персоны (ключи друзей) и другие поля, которые вам будут необходимы для уточнения истории, статуса и т.д и т.п. дружеских отношений. Только я бы и в этом случае выбрал 1-й вариант реализации.

Рабочие примеры кода работы с таблицами по ограничению ForeignKey и даже ManyToMany есть на djbook.ru
Группы, так сказать, в действии - на любом социальном (и не только) сайте :)



Офлайн

#6 Янв. 11, 2010 14:31:33

krasulya
От:
Зарегистрирован: 2010-01-09
Сообщения: 8
Репутация: +  0  -
Профиль   Отправить e-mail  

self many-to-many through

EvgIq, вы, наверно, на самом деле немного меня не поняли.

Я говорю не об отдельной группе друзья. Пример с персонами и группами я привел только для того, чтобы продемонстрировать, что я хочу от связи self many-to-many. Мне нужно реализовать “механизм дружбы” как в соцсетях. Т.е. пользователь сайта может добавить другого пользователя себе в друзья. И эта связь является двусторонней. Т.е. если пользователь добавил пользователь1 добавил пользователя2 в друзья, то в друзьях пользователя2 автоматически появляется пользователь1.



Офлайн

#7 Янв. 11, 2010 15:06:58

EvgIq
От:
Зарегистрирован: 2009-11-14
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

self many-to-many through

Это можно (а я думаю и нужно) реализовать описанным мною способом. В таблице, описывающей отношение 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)

Офлайн

#8 Янв. 12, 2010 13:01:28

Александр Кошелев
От: Москва
Зарегистрирован: 2007-02-03
Сообщения: 1724
Репутация: +  2  -
Профиль   Отправить e-mail  

self many-to-many through

EvgIq
А уж связь ManyToMany самой таблицы к себе, я, если честно, не представляю зачем может понадобиться (кстати при явном объявлении такого поля - Django тоже у вас ругается, значит я не одинок smile).
Как не странно это может понадобиться в ситуации которую описал топик стартер. И уже, наверно, не поверите вы, но сделать M2M на себя можно. Но как уже отметил топикстартер этого нельзя сделать через явно заданную through таблицу.

Но опять-таки, повторюсь, что никто не мешает сделать эту связь вручную:

class Friendship(models.Model):
who = models.ForeignKey(Person, related_name='whom_friendships')
with_whom = models.ForeignKey(Person, relate_name='with_whom_friendships')
# тут любые другие нужные поля
Безусловно такая схема требует большой продуманности логики, с ней работающей (например для тех случаев, когда бизнес правила не требуют наличия двух перекрестных ссылок для того чтобы считать факт дружбы свершившимся), но всё-равно имеет право на жизнь.

EvgIq
Если вы планируете группировать Персоны только по одной группе “Друзья”,и точно уверенны, что больше групп не будет, тогда надо только 2 таблицы - Персоны и Друзья. Где в таблице друзья будет 2-а поля с id из таблицы Персоны (ключи друзей) и другие поля, которые вам будут необходимы для уточнения истории, статуса и т.д и т.п. дружеских отношений.
Вот именно тоже самое делает M2M('self').

EvgIq
Вы на протяжении всего топика всячески пытаетесь запутать топикстартера, советуя ему трудные пути решения легких для Джанги задач. Пожалуйста не надо этого делать.
EvgIq
Понятно, что ORM Django пытается “упростить” создание и работу с отношением данного вида, но мне (лично мне, другим - не знаю) это кажется лишним
Тогда лишним должна стать вся Джанга потому что она есть по сути сахар вокруг WSGI интерфейса, логики обработки запроса и ввода/вывода данных. Но как вы понимаете это и есть её цель – упрощение. А значит глупо отказываться от удобств, которые она предоставляет.

PS: одиноки:-) к счастью.



Офлайн

#9 Янв. 12, 2010 14:32:43

EvgIq
От:
Зарегистрирован: 2009-11-14
Сообщения: 57
Репутация: +  0  -
Профиль   Отправить e-mail  

self many-to-many through

Заранее извиняюсь перед krasulya, в следующих буквах не ничего ценного по теме…
Уважаемый Daevaorn.
Странный у Вас подход, я бы даже сказал - не последовательный.
Вы пишете

Но как уже отметил топикстартер этого нельзя сделать через явно заданную through таблицу.
теперь мои слова насчет “одиночества” :)
(кстати при явном объявлении такого поля - Django тоже у вас ругается, значит я не одинок smile).
теперь Ваш PS
PS: одиноки:-) к счастью.
Что-то, наверное, я не понимаю. Или затронул-обидел Вас чем-то (В своем первом ответе в этой теме:“…Просто интересно - какой ответ вы ожидаете?…”. Но мне правда интересно было, я не стал тогда обсуждать Ваш ответ-“отписку” т.к. топикстартер сам ответил, где искать ответ на ошибку), извините не хотел, но в любом случае рад, что кого-то осчастливил, хоть и не пойму чем.

Связь ManyToMany по любому делается путем создания дополнительной таблицы. Я с этим не спорю, а даже наоборот.Я и не призываю не использовать “сахар” Django. Если Вы бы повнимательнее почитали, то я конкретно в том месте написал “…лично мне…”. Так же и в других постах, я пытался объяснить сугубо мое мнение на предмет организации подобной структуры. По моему форум для этого и существует. Не знал, что для выражения личного мнения здесь, надо спрашивать Вашего разрешения. Оставьте координаты - впредь буду слать посты для рецензии.

Все ответы я давал по организации структуры БД согласно ТЗ топикстартера. Покажите, где тут я советую
трудные пути решения легких для Джанги задач
Тем более, что Вы после нелогичной критики сами же пишите:
Вот именно тоже самое делат M2M('self').
В ваших ответах конструктива, по моему, гораздо меньше.



Офлайн

#10 Авг. 2, 2013 10:12:56

malinich
От:
Зарегистрирован: 2012-02-09
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

self many-to-many through

хотя ответ спустя 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')

цитата от туда



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version