如何解决在Django 3 / Python中,删除孤立记录的首选方法是什么?
我正在使用Django 3和Python 3.8。我有以下模型...
class Coop(models.Model):
objects = CoopManager()
name = models.CharField(max_length=250,null=False)
types = models.ManyToManyField(CoopType,blank=False)
addresses = models.ManyToManyField(Address)
enabled = models.BooleanField(default=True,null=False)
phone = models.ForeignKey(ContactMethod,on_delete=models.CASCADE,null=True,related_name='contact_phone')
email = models.ForeignKey(ContactMethod,related_name='contact_email')
web_site = models.TextField()
请注意“电话”和“电子邮件”外键列。是否有任何Django / Python特定的方法可以将ContactMethod记录变为孤立后自动删除它们?也就是说,如果我有我的模型,则在其中填充两列,然后运行
coop.phone = None
coop.save(update_fields=['phone'])
有什么东西可以自动删除孤立记录吗?还是我想实现这一目标的标准方法是什么?我正在运行MysqL 8数据库,但我希望排除特定于数据库的解决方案。
解决方法
您可以定义Django信号,但是Django信号并不总是运行。特别是当您进行执行批量更新或批量删除的ORM调用时。例如,如果您将所有email
中的phone
和/或Coop
设置为enabled=False
和Coop.objects.filter(enabled=False).update(email=None,phone=None)
,则它将不会运行post_save
信号,因此某些ContactMethod
可以孤立而无需触发信号。
即使您可以使用信号,也可能不是一个好主意。还可以在没有ORM查询的情况下对数据库进行更新,例如通过 PhpMyAdmin 前端的数据库管理员。因此,即使在Django中可行,这也意味着人们仍然可以通过另一种方式孤立对象。此外,这样的信号一次只能处理一个ContactMethod
,这比删除 bulk 中的ContactMethod
要昂贵。
您可以设置management command [Django-doc],使其可以定期运行,例如每天运行一次。您可以在 app
中定义这样的管理命令:
app/
__init__.py
models.py
management/
__init__.py
commands/
__init__.py
remove_orphan_contactmethod.py
urls.py
views.py
然后在app/management/commands/remove_orphan_contactmethod.py
中,您可以检测并删除以下ContactMethod
对象:
from django.core.management.base import BaseCommand,CommandError
from app.models import ContactMethod
class Command(BaseCommand):
help = 'Remove ContactMethods not referenced through email or phone'
def handle(self,*args,**options):
items = ContactMethod.objects.filter(
contact_phone=None,contact_email=None
).delete()
number = items.get('app.ContactMethod',0)
self.stdout.write(self.style.SUCCESS(f'Removed {number} ContactMethod object(s)'))
然后您可以运行:
python3 manage.py remove_orphan_contactmethods
运行命令。例如,您可以指定cronjob [wiki]或其他一些重复执行的任务机制,以一定频率执行此命令。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。