【问题标题】:How to call a function when you delete a model object in django admin page? (or override delete action?)在 django 管理页面中删除模型对象时如何调用函数? (或覆盖删除操作?)
【发布时间】:2022-11-09 21:06:20
【问题描述】:

每当我通过管理页面删除模型对象时,我都需要调用一个函数。我怎么能做这样的事情?

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    是的,它被称为 post_delete 信号。这是一种方法(您可以将其添加到您的 models.py 文件的底部,或者至少在您的模型之后:

    from django.db.models.signals import post_delete
    from django.dispatch import receiver
    
    @receiver(post_delete, sender=YourModelName)
    def signal_function_name(sender, instance, using, **kwargs):
        your_function(args)
    

    删除对象后将调用此函数。 other types of signals.中还有pre_save、post_save

    该信号将在从管理员中删除或任何地方的任何删除操作(您的其他逻辑、视图、python shell 等)中调用。

    【讨论】:

    • 太感谢了。您能否告诉我,当我使用 pre_delete 时,如何访问将要删除的对象?我在该对象中有一个外键,并想更改其中的某些内容。
    • 别客气!请注意,信号接收模型对象的实例,因此您可以将 FK 字段作为 instance.your_field_name 等进行操作。希望这是有道理的。在保存后信号中调用 save() 时要小心,因为您可以创建无限循环。使用 update() 是一种解决方法。
    【解决方案2】:

    在您的应用程序目录中创建一个文件signals.py,例如,当文章被删除时,我试图从文章作者中删除所有相关标签。

    from django.db.models.signals import post_delete
    from django.dispatch import receiver
    
    from articles.models import Article
    from common.methods import tagClear
    
    @receiver(post_delete, sender=Article)
    def authorTagClear(sender, instance, using, **kwargs):
        tagClear(instance, instance.author, against=1)
    

    apps.py 中定义一个就绪方法,这将在应用程序运行时插入signals

    from django.apps import AppConfig
    
    
    class ArticlesConfig(AppConfig):
        default_auto_field = 'django.db.models.BigAutoField'
        name = 'articles'
    
        def ready(self):
            import articles.signals
            return super().ready()
    

    【讨论】:

      【解决方案3】:

      您在模型上的正常删除功能将不起作用,解决此问题的一种方法是使用 post delete sgnal 在您的应用目录中创建一个文件 signals.py

      #signals.py
      from django.db.models.signals import post_delete
      from django.dispatch import receiver
      
      @receiver(post_delete, sender=ModelName)
      def deleting_model(sender, instance, **kwargs):
          #your action goes here
          pass
      

      然后在你的 apps.py 中定义 ready 方法

      #apps.py
      from django.apps import AppConfig
      
      
      class AppNameConfig(AppConfig):
          default_auto_field = 'django.db.models.BigAutoField'
          name = 'appname'
      
          def ready(self):
              import appname.signals
      

      【讨论】:

        【解决方案4】:
        def delete(self):
        files = WidgetFile.objects.filter(widget=self)
        if files:
            for file in files:
                file.delete()
        super(Widget, self).delete()
        

        这触发了每个相关对象上必要的 delete() 方法,从而触发了我的自定义文件删除代码。是的,它的数据库成本更高,但是当您尝试删除硬盘上的文件时,多打几次数据库并不是什么大开销。

        【讨论】:

        • for 循环不需要删除过滤查询集中的所有对象。您可以在查询集本身上调用 delete()。
        猜你喜欢
        • 2013-06-30
        • 1970-01-01
        • 2013-02-18
        • 1970-01-01
        • 1970-01-01
        • 2013-08-06
        • 1970-01-01
        • 2017-04-07
        • 1970-01-01
        相关资源
        最近更新 更多