[Django]-How to delete a record after a certain time of it's creation in Django?

8👍

The most robust way to do this is typically a combination of filtering, and removing the items with a task you run every hour/day/week.

We thus can retrieve the items that are not yet expired with:

from django.db.models.functions import Now

stories = Story.objects.filter(expiration_time__lt=Now())

If you need to filter often, it might be more interesting to make a manager [Django-doc] for this.

from django.db import models
from django.db.models.functions import Now

class StoryManager(models.Manager):

    def get_queryset(self, *args, **kwargs):
        return super().get_queryset(*args, **kwargs).filter(
            expiration_time__lt=Now()
        )


class Story(models.Model):
    # …
    xpiration_time = models.DateTimeField(db_index=True)
    
    objects = StoryManager()

The db_index=True part [Django-doc] will normally improve performance to filter expired objects.

Of course this does not remove the elements, it simply will not retrieve these (and thus if you filter these in the views, then you will not see these).

You can make a periodic task, for example a cronjob [wiki] that will run every day, week, month, hour to remove the elements. You can do this by defining a management command [Django-doc]:

# app_name/management/commands/remove_expired_stories.py

from django.core.management.base import BaseCommand
from django.db.models.functions import Now

from app_name.models import Story

class Command(BaseCommand):
    help = 'Remove expired stories'

    def handle(self, *args, **options):
        Story._base_manager.filter(expiration_time__gte=Now()).delete()

Then you can manually run:

python3 manage.py remove_expired_stories

or you can schedule this task to run periodically. This is more robust: if for some reason the scheduler does no longer work, then the filtering will still prevent that you can see the Storys that are expired. It is also simpler and more efficient than scheduling an expiration script per story, especially since if later the expiration time changes, it will be quite complicated to remove the scheduled items, and reschedule these.

1👍

I have learned that it simple solutions are often better than more beautiful, complex ones.

If this were me, I would run a scheduled process that runs once an hour and checks each row in the sql table. Then, check if post time was greater than 24 hours ago.

If you really want to get fancy, I would recommend Redis to create a scheduled process upon creation of the post. Schedule a task in 24 hours that deletes that particular post.

0👍

I think willem van onsem is right… i mean his method

       ###LOGIC 

time A i.e Now()---------somwhere in the future -------------------------timeB i.e expiration_time
if time A > time B its expired 
if time A < time B its not expired  

so with

  ...
 expiration_time = models.DateTimeField(db_index= True,default=Now()+timedelta(days=1), editable = False)

in your models and in your manager

class StoryManager(models.Manager):

def get_queryset(self, *args, **kwargs):
    return super().get_queryset(*args, **kwargs).filter(
        expiration_time__gt=Now()
    )

then in the command/.py this
class Command(BaseCommand):
help = "clear expired messages"

def handle(self, *args, **options):
    Story._base_manager.filter(expiration_time__lte=Now()).delete()
    

all should be well.

Leave a comment