Reputation: 1549
In Django, I have a many to many relationship between two models.
I want to remove an instance of model_one from several instances of model_two.
I have:
user = User.objects.get(id=user_id)
conversations = Conversation.objects.filter(users=user)
for conversation in conversations.iterator():
conversation.users.remove(user)
This needs to evaluate every single instance of Conversation. Is there a way to do this without iteration?
UPDATE:
Added the models to add clarity to the question.
class User(EditMixin):
conversations = models.ManyToManyField('Conversation', related_name='users')
name = models.CharField(max_length=255, blank=True, null=True)
permalink = models.URLField(blank=True, max_length=2083)
rating = models.DecimalField(decimal_places=2, max_digits=4, blank=True, default=0)
remote_id = models.CharField(max_length=4096, blank=True, null=True)
summary = models.CharField(max_length=255, blank=True, null=True)
objects = UserManager()
class Meta:
verbose_name_plural = 'Users'
class Conversation(EditMixin, BasicInfoMixin):
content = models.TextField(blank=True, null=True)
update_enabled = models.BooleanField(default=False)
objects = ConversationManager()
class Meta:
verbose_name_plural = 'Conversations'
UPDATE 2:
I think my question is unclear. The clear() method removes all items in a m2m field. What I would like to do is the following:
I have a queryset of User objects. Each has a m2m field with conversations. Every item in the queryset has conversation 7 in the m2m field, but also contains other conversations. I want to only remove conversation 7 from the m2m of every object in the queryset, while maintaining the other conversations. All of this, without iteration if possible, e.g.
before:
Jeremy.conversations: [1, 2, 3, 4, 7]
Tiffany.conversations: [3, 7, 9]
Jeff.conversations: [5, 6, 7]
after:
Jeremy.conversations: [1, 2, 3, 4]
Tiffany.conversations: [3, 9]
Jeff.conversations: [5, 6]
Upvotes: 5
Views: 5579
Reputation: 15758
You could use something like this
user = User.objects.get(id=user_id)
user.conversation_set.clear()
if it from other end on many to many (applicable to your solution after edit )
user.conversations.clear()
You could then have multiple elements as args in remove
user.conversations.remove(*conversations)
or use .through to access pivot table and delete from it
Upvotes: 4