Django supprimant un objet de la relation ManyToMany

112

Comment supprimer un objet d'une relation plusieurs-à-plusieurs sans supprimer l'objet réel?

Exemple:

J'ai les modèles Moodset Interest.

Mooda un champ plusieurs-à-plusieurs interests(qui est a models.ManyToManyField(Interest)).

Je crée une instance de Moodscalled my_mood. Dans my_moodsle domaine des intérêts que j'ai my_interest, c'est-à-dire

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

Comment supprimer my_interestde my_moodsans supprimer l'une ou l'autre des instances de modèle? En d'autres termes, comment supprimer la relation sans affecter les modèles associés?

Nachshon Schwartz
la source

Réponses:

183
my_mood.interests.remove(my_interest)

Documents sur les relations de Django

Remarque: vous devrez peut-être obtenir une instance de my_moodet my_interestutiliser l'API QuerySet de Django avant de pouvoir exécuter ce code.

DrTyrsa
la source
3
AttributeError: 'RelatedManager' object has no attribute 'remove'
Cerin
1
pour en ajouter un autreentry my_mood.interests.add(my_interest)
Zohab Ali
65

Si vous devez supprimer toutes les références M2M sans toucher les objets sous-jacents, il est plus facile de travailler dans l'autre sens:

interest.mood_set.clear()

Bien que cela ne répond pas directement à la question du PO, c'est souvent utile dans cette situation.

shacker
la source
10
Pourquoi ce vote a-t-il été rejeté? Certes, cela ne répond pas spécifiquement à la question du PO, mais j'ai laissé la réponse car elle présente un intérêt spécifique pour les personnes aux prises avec la suppression de relations dans des contextes M2M et supprime le besoin de parcourir les instances. J'ai pensé que c'était une astuce connexe utile.
shacker
2
C'était juste utile pour moi (j'étais sur le point de faire une boucle et je ne voulais pas). Merci de l'avoir posté!
bwv549
1
cela pourrait être mieux si vous ajoutez simplement ce point dans la réponse ci-dessus
brainLoop
1
Ou avec un nom similaire dans les modèles etinterest.relatedname.clear()
Josh
11

Dans votre cas, vous pouvez simplement effacer la relation

my_mood.interests.clear()

Ensuite, peut-être que lorsque vous créez à nouveau une nouvelle relation dans votre sérialiseur, vous pouvez faire quelque chose comme ça

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