在使用Django框架及其.delete()方法。我使用以下型号的
class Message(models.Model):
...
sender = models.ForeignKey(User, related_name="%(class)s_sender")
user = models.ManyToManyField(User, related_name="%(class)s_recip")
trash = models.ManyToManyField(User, related_name="%(class)s_trash", blank=True)
...
因此,我的目标是检查M2M字段"user"one_answers"trash"是否不再包含对象/密钥,如果是,则应从数据库中删除相应的Message实例。为了存档,我使用m2m_changed信号如下
def set_recip_names(sender, instance, action,**kwargs):
print instance
if action == "post_remove":
if instance.user.all().count() == 0 and instance.trash.all().count() == 0:
print instance.id
instance.delete()
def msg_del(sender, **kwargs):
print "Message deleted"
m2m_changed.connect(set_recip_names, sender=Message.user.through)
m2m_changed.connect(set_recip_names, sender=Message.trash.through)
post_delete.connect(msg_del, sender=Message)
当然,前两个print语句是为了调试目的,它们都打印出了我所期望的内容:instance是要删除的相应实例,instance.id证实了这一点,并告诉我Django实际上将执行.delete()方法。
第二个post_delete信号也是用于调试目的的,并且它是按预期调用的,所以我得到的输出是"Message deleted"。
因此,最大的问题是,"待删除"实例仍保留在数据库中。我在网上搜索了一个小时,但没有发现我的代码有任何问题。
欢迎任何建议,或者如果你知道我想做什么更好的方法,请告诉我。
已解决问题其实很明显。我的一个代码片段,其中删除了M2M字段中的用户交互元素,看起来像
...
try:
message = Message.objects.get(id=msg)
if usr not in message.trash.all():
continue
if usr != message.sender:
message.user.remove(usr) # m2m_changed triggered
message.trash.remove(usr) # m2m_changed triggered
# if instance was removed by now, this .save() will
# insert the python-local object in the db, so it looked
# like the same instance is still there, but I saw that
# the "old" instance suddenly had a new id
message.save()
except Message.DoesNotExist:
continue
...
您可以通过以下操作直接删除记录:
YourModel.objects.get(id=instance.id).delete()
如果该记录存在,则它将在数据库中被删除。
您的实例保存在RAM中,可能不会被删除,您可以通过从RAM中删除它来手动执行此操作:del instance