1


0

同じ表Django ORMソフト削除方法いいですか?

私はDjangoでソフト削除を実装するために以下の設定を使用しています。 私はボンネットの下ではDjangoについてあまり詳しくないので、私が遭遇する可能性があることについてのフィードバックをいただければ幸いです。 私はQuerySetをサブクラス化するのに特に不快です。

基本的な考え方は、 `+ MyModel `で ` delete `を最初に呼び出すと、 ` MyModel `の ` date_deleted `が現在の日時に変更されるということです。 2番目の ` delete `は実際にオブジェクトを削除します。 ( ` delete `をキャッチするには、オブジェクトと ` QuerySet `の2つのオーバーライドが必要です。これらはオブジェクトの ` delete `メソッドをバイパスできます。)デフォルトのマネージャーは削除されたオブジェクトを隠すため、削除されたオブジェクトは消えて、 ` deleted_objects +`マネージャーを介して明示的に要求されます。

この設定を使用するには、「+ DeletionQuerySet 」と「 DeletionManager 」を定義し、モデルに「 date_deleted 」、「 objects 」、および「 deleted_objects +」を追加する必要があります。

ありがとう、

PSは、デフォルトのマネージャからオブジェクトをフィルタリングするこの方法はhttp://docs.djangoproject.com/en/dev/topics/db/managers/#do-not-filter-away-any-results-であることを言及するのを忘れてこのマネージャタイプのサブクラスのクラス[強く推奨しない]!

class DeletionQuerySet(models.query.QuerySet):

    def delete(self):
        prev_deleted = self.filter(date_deleted__isnull=False)
        prev_deleted.actual_delete()
        prev_undeleted = self.filter(date_deleted__isnull=True)
        prev_undeleted.update(date_deleted=datetime.datetime.now())

    def actual_delete(self):
        super(DeletionQuerySet, self).delete()

class DeletionManager(models.manager.Manager):

    # setting use_for_related_fields to True for a default manager ensures
    # that this manager will be used for chained lookups, a la double underscore,
    # and therefore that deleted Entities won't popup unexpectedly.
    use_for_related_fields = True

    def __init__(self, hide_deleted=False, hide_undeleted=False):
        super(DeletionManager, self).__init__()
        self.hide_deleted = hide_deleted
        self.hide_undeleted = hide_undeleted

    def get_query_set(self):
        qs = DeletionQuerySet(self.model)
        if self.hide_deleted:
            qs = qs.filter(date_deleted__isnull=True)
        if self.hide_undeleted:
            qs = qs.filter(date_deleted__isnull=False)
        return qs

class MyModel(models.Model):

    # Your fields here...
    date_deleted = models.DateTimeField(null=True)

    #the first manager defined in a Model will be the Model's default manager
    objects = DeletionManager(hide_deleted=True)
    deleted_objects = DeletionManager(hide_undeleted=True)

    def delete(self):
        if self.date_deleted is None:
            self.date_deleted = datetime.datetime.now()
            self.save()
        else:
            super(Agreement, self).delete()

1 Answer


1


私は、現在使用されている、人気のある、テクノロジーを問わず、問題のあるドメインにとらわれない、一般的なソフト削除を行う方法はないと思います。 私たちはそれが私たちが使っているものよりも歴史的/歴史志向のデータベースシステムにもっとリンクしていると思います。 私はあなたにdjangoの削除を回避しないことをお勧めします(これは完全な削除です)。 そのまま保管してください。

あなたが私たちのシステムでおそらく持っているであろう "削除"は、ケースの90%、視覚的な削除です…​

この点では、あなたの特定のドメイン問題のための削除と同義語を見つけることを試み、プロジェクトの始めからこれをしなさい。

IsVisible、IsUnpublished(IsDeletedでさえ)があなたのクエリをめちゃくちゃにすると文句を言うので、彼らはあなたが常にそれらを含めるように注意しなければならないと文句を言う…​

しかし、これは明らかにドメインの問題を無視しています。ドメインが見えないようにすることができる、または未公開になることができるオブジェクトを持っている場合 - もちろん、表示したいすべてのオブジェクトのリストを照会するときこれは、ドメインの問題が完全な形で解決される方法であるため、表示されずに未公開のオブジェクトです。

乾杯。