Django удаляет объект из отношения ManyToMany


112

Как мне удалить объект из отношения «многие ко многим», не удаляя сам объект?

Пример:

У меня есть модели Moodsи Interest.

Moodимеет поле "многие ко многим" interests(т.е. a models.ManyToManyField(Interest)).

Я создаю экземпляр Moodscall my_mood. В my_moodsполе интересов у меня есть my_interest, то есть

>>> my_mood.interests.all()
[my_interest, ...]

Как удалить my_interestиз my_moodбез удаления либо экземпляра модели? Другими словами, как мне удалить взаимосвязь, не затрагивая связанные модели?

Ответы:


183
my_mood.interests.remove(my_interest)

Документы по связям с Django

Примечание: вам, возможно, придется получить экземпляр my_moodи my_interestиспользовать Django QuerySet API, прежде чем вы сможете выполнить этот код.


3
AttributeError: 'RelatedManager' object has no attribute 'remove'
Cerin

1
чтобы добавить ещеentry my_mood.interests.add(my_interest)
Зохаб Али

65

Если вам нужно удалить все ссылки M2M, не касаясь нижележащих объектов, проще работать в другом направлении:

interest.mood_set.clear()

Хотя это напрямую не касается вопроса OP, это часто бывает полезно в этой ситуации.


10
Почему это было отклонено? Конечно, он не касается конкретно вопроса OP, но я оставил ответ, потому что он представляет особый интерес для людей, борющихся с удалением отношений в контекстах M2M, и устраняет необходимость в циклическом просмотре экземпляров. Я подумал, что это полезный совет по теме.
shacker

2
Это было просто полезно для меня (я собирался перебирать и не хотел). Спасибо, что разместили!
bwv549 09

1
было бы лучше, если бы вы просто добавили этот момент в ответ выше
brainLoop

1
Или со связанным именем в моделях иinterest.relatedname.clear()
Джош

11

В вашем случае вы можете просто очистить отношения

my_mood.interests.clear()

Тогда, возможно, когда вы снова создадите новое отношение в своем сериализаторе, вы сможете сделать что-то вроде этого

interests = Interests.objects.get_or_create(name='Something')
my_mood_obj.tags.add(tag[0])
my_mood_obj.save()
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.