django 多对多关系:如何删除项目但不从相关模型中删除它们
Posted
技术标签:
【中文标题】django 多对多关系:如何删除项目但不从相关模型中删除它们【英文标题】:django many-to-many relationships: how to remove items but not delete them from related Models 【发布时间】:2012-03-16 00:50:56 【问题描述】:Django 新手问题。我有以下型号:
class Leg(models.Model):
drive_date = models.DateField()
startpoint = models.CharField(max_length=50)
endpoint = models.CharField(max_length=50)
start_time = models.TimeField()
riders = models.ManyToManyField(Rider, blank=True)
drivers = models.ManyToManyField(Driver, blank=True)
carpool = models.ForeignKey(Carpool, blank=True, null=True)
对于某些 Leg 实例,我想从 Leg 模型中删除任何现有的骑手和司机,但不要分别从骑手或司机模型(未显示)中删除它们。不知道该怎么做。当我迭代时:
for driver in leg.drivers.all():
driver.delete()
它似乎删除了实际的 Driver 对象,我不想这样做。
非常感谢任何帮助。谢谢!
【问题讨论】:
【参考方案1】:从关系中删除项目的正确代码是:
for driver in leg.drivers.all():
leg.drivers.remove( driver )
【讨论】:
【参考方案2】:我可能会采用的一种方法是为 Driver 模型创建一个自定义管理器。以下未经测试的代码:
from django.db import models
class DriverManager(models.Manager):
def get_query_set(self):
return super(DriverManager, self).get_query_set().filter(removed=False)
class Driver(models.Model):
# new stuff to add ...
removed = models.BooleanField(default=False)
objects = models.Manager() # default manager
active = DriverManager() # custom manager
说明:新字段removed
已添加到驱动程序模型中。您没有删除记录,而是将其设置为 True 并保存。然后,在您通常过滤 Driver.objects 的地方,改用 Driver.active。
【讨论】:
非常感谢您的回复。似乎在您提供的示例中,驱动程序将被“删除”或“未删除”,这将适用于所有腿。但是我只需要为某些 Leg 实例删除驱动程序,但对于其他实例仍然存在,所以我不确定它是否会工作。但我会试一试。再次感谢。 抱歉,我以为您想有选择地从支路中删除驱动程序,而不是删除它们。在您的情况下,只需分配 leg.drivers = None,然后分配 leg.save()。 再次感谢。我以为这很简单。【参考方案3】:这样做
leg.drivers.clear()
.clear() to completely remove completely(efficiently)
.remove(<related obj>) to remove one relation
.remove([<related obj>, <related obj>...]) to remove one or more relation
【讨论】:
以上是关于django 多对多关系:如何删除项目但不从相关模型中删除它们的主要内容,如果未能解决你的问题,请参考以下文章
Laravel 5:如何更新与多对多相关的项目(删除+添加)