Уведомления

Группа в Telegram: @pythonsu

#1 Янв. 9, 2010 15:42:52

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

self many-to-many through

Добрый день.

Знаком с Djangо всего несколько дней. Поиском по форуму и гуглом пользовался - не помогло. Нужно реализовать симметричную связь self many-to-many с возможностью хранения дополнительный данных каждой отдельной связи. Т.е. то, что в остальных случаях достигается с помощью промежуточного класса. А симметричная связь многие-ко-многим через другой класс, как я понял, невозможна.

Можно ли это сделать? Или придется использовать несимметричную связь? Спасибо.



Офлайн

#2 Янв. 9, 2010 20:02:20

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

self many-to-many through

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



Офлайн

#3 Янв. 10, 2010 07:45:13

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

self many-to-many through

Например, я хочу сделать возможность пользователям “дружить”. Сделать это можно так.

class Person(models.Model):
...
friends = models.ManyToManyField('self')
Но, например, нужна возможность подтверждать дружбу. Т.е. нужно, чтобы где-то хранилась информация об этой связи (например, active, date и т.п.)

Если делать связь между разными таблицами, то это будет выглядеть так:

class Person(models.Model):
...
groups = models.ManyToManyField('Group', through='Membership')

class Group(models.Model):
...

class Membership(models.Model):
...
group = models.ForeignKey(Group)
person = models.ForeignKey(Person)

# дополнительная информация о связи
date_entered = models.DateTimeField(auto_now_add=True)
status = models.IntegerField()
В классе membership и будет содержатсья дополнительная инофрмация. И, если я захочу выбрать из определенной группы всех пользвателей, вступивших в 2007 году, сделаю так:

persons = Group.person_set.objects.filter(membership__date_entered__year=2007)
Но в django нельзя реализовать связь многие-ко-многим к себе самому через какой-то другой класс. Что можно сделать?



Отредактировано (Янв. 10, 2010 07:46:03)

Офлайн

#4 Янв. 10, 2010 09:28:57

ziro
От:
Зарегистрирован: 2009-08-13
Сообщения: 225
Репутация: +  8  -
Профиль   Отправить e-mail  

self many-to-many through

А Вы случайно http://pinaxproject.com/ не смотрели еще? Там схожий функционал реализован.



Офлайн

#5 Янв. 10, 2010 11:23:50

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

self many-to-many through

krasulya
Но в django нельзя реализовать связь многие-ко-многим к себе самому через какой-то другой класс.
Почему нельзя?



Офлайн

#6 Янв. 10, 2010 17:27:07

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

self many-to-many through

Daevaorn
Почему нельзя?
Просто интересно - какой ответ вы ожидаете?

krasulya
Например, я хочу сделать возможность пользователям “дружить”. Сделать это можно так.
Связь MаnyToMаny - все равно создает отдельную таблицу (на мой вкус, совершенно не нужная “фича”).
Конечно кому-то это может и нравится, но я предпочитаю “по старинке”
Т.е. Есть таблица - Persons, и таблица - Groups. Так же есть таблица PersonInGroup которая содержит ключи из Persons и Groups. Так же в нее вы можете включить и всю другую инфу о Person (когда он в нее вошел, какой у него в ней статус и т.п. и т.д)



Отредактировано (Янв. 10, 2010 17:38:31)

Офлайн

#7 Янв. 10, 2010 19:47:02

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

self many-to-many through

EvgIq
Daevaorn
Почему нельзя?
Просто интересно - какой ответ вы ожидаете?

krasulya
Например, я хочу сделать возможность пользователям “дружить”. Сделать это можно так.
Связь MаnyToMаny - все равно создает отдельную таблицу (на мой вкус, совершенно не нужная “фича”).
Конечно кому-то это может и нравится, но я предпочитаю “по старинке”
Т.е. Есть таблица - Persons, и таблица - Groups. Так же есть таблица PersonInGroup которая содержит ключи из Persons и Groups. Так же в нее вы можете включить и всю другую инфу о Person (когда он в нее вошел, какой у него в ней статус и т.п. и т.д)
Отдельная таблица для отображения связи есть в любом случае. Но если это автоматически создаваемая таблица ManyToMany, то в ней нет никаких полей. И если их добавить в ручную, от этого не будет пользы - их нельзя будет использовать при запросе.

А насчет связи, описанной вами, вы имеете в виду это:
class Person(models.Model):
...

class Group(models.Model):
...

class PersonInGroup(models.Model):
person = models.ForeignKey(Person)
group = models.ForeignKey(Group)
Если да, то как я могу получить доступ из объекта person ко всем его группам?



Офлайн

#8 Янв. 10, 2010 19:55:48

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

self many-to-many through

Daevaorn
krasulya
Но в django нельзя реализовать связь многие-ко-многим к себе самому через какой-то другой класс.
Почему нельзя?
Об этом говорится в документации. А первопричину назвать, к сожалению, не могу.

И при попытке синхронизировать базу данных (python manage.py syncdb), имея такие модели:
class Person(models.Model):
...
friends = models.ManyToManyField('self', through='Friendship')

class Friendship(models.Model):
...
Возникает ошибка “Many-to-many fields with intermediate tables cannot be symmetrical”.



Офлайн

#9 Янв. 10, 2010 19:57:28

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

self many-to-many through

ziro
А Вы случайно http://pinaxproject.com/ не смотрели еще? Там схожий функционал реализован.
Пока нет. Посмотрю, спасибо.



Офлайн

#10 Янв. 10, 2010 20:22:28

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

self many-to-many through

1. Зачем вы из Person делаете ссылку на эту же таблицу Person? Да еще ManyToMany? Pesron - просто линейный список, в нем “деревья” не нужны.
2. Связь ManyToMany вам нужна между Person и Group. Вы ее создали - таблица Membership. В нее вы можете добавлять (и вроде добавили уже) все дополнительные поля про пользователя в группе.
3. Я лишь сказал, что можно все сделать и без ManyToMany. Просто вам придется тогда явно запрашивать пользователей в группе, или группы пользователя из предложенной мной таблицы PersonInGroup. Все исходные данные для этого у вас есть.



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version