6

私はdjango管理者でソフト削除を使用しています。問題は、外部キー項目を削除すると、リンクされているすべての項目の削除がトリガーされないように見えることです。または、そうかもしれませんが、モデルにあるカスタム定義削除を実行していません。

-個人を削除すると、論理的に削除されますが、関連するアカウントはそのまま残ります。

-論理的な削除を削除すると、個人を削除するとアカウントも削除されますが、これは正しいです。

したがって、理想的には、個人を削除するときに、個人をソフト削除し、その個人を参照しているアカウントもソフト削除します(非アクティブとしてマークします)。

class Person(models.Model):
    description = models.CharField(max_length=100)

    def delete(self, *args, **kwargs):
        self.active = False
        self.deleted_date = datetime.now()
        self.save()

class Account(models.Model):
    name = models.CharField(max_length=50)
    person = models.ForeignKey(Person, null=True, blank=True)
    active = models.BooleanField(default=True, editable=False)

    objects = SoftDeleteManager()

    def delete(self, *args, **kwargs):
        self.active = False
        self.deleted_date = datetime.now()
        self.save()

    def __unicode__(self):
        return "%s: %s" % (self.type,self.name)

更新:質問を更新しました。Person モデルでソフト削除を実行しているとは言いませんでした。また、def の削除がオーバーライドされていない場合、カスケードの削除が機能することを追加しましたが、削除をオーバーライドすると、カスケードはトリガーされません。

4

2 に答える 2

4

Personモデルは現在、「ソフト」削除用に設計されていません。オブジェクトを削除するPersonと、Django は関連するすべてのオブジェクトを削除しAccountます。オブジェクトを論理的に削除するPerson場合は、そのフラグをPersonモデルに追加します。Account次に、既定のマネージャーが、論理的に削除された Person オブジェクトに関連するアカウントを除外していることを確認する必要があります。

編集:

  1. 1 つのアプローチは、非アクティブな Person オブジェクトに関連するオブジェクトを "deleted" に設定するのではなく、デフォルトのマネージャーに除外させることです。

      class AccountManager(models.Manager): 
          def get_query_set(self):
              return self.filter(person__active=True).filter(active=True)
    
  2. もう 1 つの方法は、Person オブジェクトがソフト削除されたときに、関連する Account オブジェクトを「削除済み」に設定することです。そのために、シグナルを使用できます。Person オブジェクトの保存後のシグナルは適切だと思います。

于 2011-07-04T09:05:00.663 に答える
0

別の解決策は、最近 github に登場した Django パッケージである django-softdelete を使用することです: https://github.com/scoursen/django-softdelete

モデルに提供された SoftDeleteObject mixin を使用する場合、それらを削除すると、関連するすべてのモデルも自動的にソフト削除されます。さらに優れているのは、ソフト削除に関連するすべてのモデルが保存されるため、1 回の削除取り消し呼び出しですべてのモデルの削除を取り消すこともできます。

于 2011-08-12T20:31:47.973 に答える