Django entfernt Objekt aus der ManyToMany-Beziehung

112

Wie würde ich ein Objekt aus einer Viele-zu-Viele-Beziehung löschen, ohne das eigentliche Objekt zu entfernen?

Beispiel:

Ich habe die Modelle Moodsund Interest.

Moodhat ein Viele-zu-Viele-Feld interests(das ist a models.ManyToManyField(Interest)).

Ich erstelle eine Instanz von Moodsaufgerufen my_mood. In my_moods'Interessenbereich habe ich my_interestBedeutung

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

Wie entferne ich my_interestaus , my_moodohne entweder Modellinstanz löschen? Mit anderen Worten, wie entferne ich die Beziehung, ohne die zugehörigen Modelle zu beeinflussen?

Nachshon Schwartz
quelle

Antworten:

183
my_mood.interests.remove(my_interest)

Djangos Beziehungsdokumente

Hinweis: Möglicherweise müssen Sie eine Instanz der QuerySet-API von Django abrufenmy_mood und my_interestverwenden, bevor Sie diesen Code ausführen können.

DrTyrsa
quelle
3
AttributeError: 'RelatedManager' object has no attribute 'remove'
Cerin
1
um eine weitere hinzuzufügenentry my_mood.interests.add(my_interest)
Zohab Ali
65

Wenn Sie alle M2M-Referenzen entfernen müssen, ohne die zugrunde liegenden Objekte zu berühren, ist es einfacher, aus der anderen Richtung zu arbeiten:

interest.mood_set.clear()

Dies geht zwar nicht direkt auf die Frage des OP ein, ist jedoch in dieser Situation häufig nützlich.

Shacker
quelle
10
Warum wurde das abgelehnt? Zugegeben, es geht nicht speziell auf die Frage des OP ein, aber ich habe die Antwort hinterlassen, da sie von besonderem Interesse für Personen ist, die sich mit dem Entfernen von Beziehungen in M2M-Kontexten auseinandersetzen, und die Notwendigkeit beseitigt, Instanzen zu durchlaufen. Ich dachte, es wäre ein hilfreicher Tipp.
Shacker
2
Dies war nur nützlich für mich (ich wollte mich gerade durchschleifen und wollte es nicht). Danke, dass du es gepostet hast!
bwv549
1
Es könnte besser sein, wenn Sie nur diesen Punkt in der obigen Antwort hinzufügen
brainLoop
1
Oder mit verwandtem Namen in Modellen undinterest.relatedname.clear()
Josh
11

In Ihrem Fall können Sie einfach die Beziehung löschen

my_mood.interests.clear()

Wenn Sie dann in Ihrem Serializer erneut eine neue Beziehung erstellen, können Sie möglicherweise Folgendes tun

interests = Interests.objects.get_or_create(name='Something')
my_mood_obj.tags.add(tag[0])
my_mood_obj.save()
Sabyasachi
quelle