Aside from the good and bad stories of logical deletion, in financial systems etc., any past data should not be deleted in the physical history (for a certain period of time), and logical deletion may be used. I've seen some articles on how to implement logical deletion in DRF, but since we implemented it this way, we'll take the plunge and publish it.
class XQuerySet(models.QuerySet):
def get_or_none(self, *args, **kwargs):
try:
return super(XQuerySet, self).get(*args, **kwargs)
except ObjectDoesNotExist:
return None
def delete(self):
"""
Logical deletion
Model.objects.all().delete()
:return:
Number of deleted cases
"""
return super(XQuerySet, self).update(is_active=False, deleted=now_tz())
def delete_hard(self):
"""
Physical deletion
Model.objects.all().delete_hard()
:return:
Number of deleted cases
"""
return super(XQuerySet, self).delete()
class XModelManager(models.Manager):
def get_or_none(self, **kwargs):
try:
return self.get(**kwargs)
except ObjectDoesNotExist:
return None
def get_queryset(self):
return XQuerySet(self.model)
class XModelManagerActive(XModelManager):
def get_queryset(self):
return XQuerySet(self.model).filter(is_active=True)
class XModel(TimeStampedModel):
is_active = models.BooleanField(
default=True,
editable=False,
help_text="Flag for logical deletion"
)
deleted = models.DateTimeField(
null=True,
default=None,
editable=False,
help_text="Logically deleted time"
)
"""
Manager used for normal search
What was logically deleted is not displayed
"""
objects = XModelManagerActive()
"""
Manager used for global search
Display including logically deleted ones
"""
entire = XModelManager()
def delete(self, using=None, keep_parents=False, is_hard=False):
if is_hard:
return super().delete(using, keep_parents)
else:
self.deleted = now_tz()
self.is_active = False
self.save(using)
return 1, {}
def delete_hard(self, using=None, keep_parents=False):
self.delete(using, keep_parents, is_hard=True)
class Meta:
abstract = True
I made two ModelManagers and used them properly, but since the basic (usually used) is ʻobjects`, it is a mechanism that logically deletes without the programmer being aware of it.
class Category(XModel):
name = models.CharField(
max_length=32,
null=False,
blank=False,
default="",
help_text="Category name"
)
key = models.CharField(
max_length=32,
null=False,
blank=False,
default="",
help_text="Category name English"
)
It just inherits from XModel. It also comes with get_or_none
.
For example, if you want to access the data that was logically deleted by Admin etc., you can do this
@admin.register(Category)
class AdminUserAdmin(admin.ModelAdmin):
list_display = ('key', 'name')
def get_queryset(self, request):
return self.model.entire.all()
XTech uses the Django REST framework
to develop the API. We have a lot of extensions that can reach the itchy part of the DRF, so I'd like to publish it as much as possible, so stay tuned.
Recommended Posts