0

Here I am writing a middleware to delete objects older than 3 months. The date_before_2_month and datetime_before_2_months is working fine. I haven't tested yet for filtering But in my console it is giving me a runtime warning saying activity_time received a naive datetime.

Is this warning a issue(needs to solve) or we can ignore it ?

Also does my filter parameters are good for querying the objects from model which are 2 months old ?

activity_time in model is DateTimeField(auto_now_add=True)

class UserActivityLogDeleteMiddleware(object):  # middleware for deleting user activity logs which are older than 2 months

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        date_before_2_month = datetime.date.today() - relativedelta(months=2) 
        # converting into datetime
        datetime_before_2_month = datetime.datetime.combine(date_before_2_month, datetime.time(9, 00, 00))
        # deleting logs older than 2 months
        UserActivityLog.objects.filter(activity_time__lt=datetime_before_2_month).delete()

        response = self.get_response(request)
        return response
D_P
  • 802
  • 10
  • 32
  • You deletion query looks good to me, regarding the naive datetime check this answer: https://stackoverflow.com/questions/18622007/runtimewarning-datetimefield-received-a-naive-datetime – JSRB Jun 23 '20 at 09:28

1 Answers1

1

Generally you want to keep your datetimes timezone aware if you're using timezones through your app.

There are a couple of improvements I can see to your code. When using relativedelta you can set the hour and minute to make life a bit easier.

from django.utils import timezone

...

def __call__(self, request):
    # Getting a datetime for 2 months ago at 9am
    dt_2_months_ago = timezone.now() - relativedelta(months=2, hour=9, minute=0) 

    # deleting logs older than 2 months
    UserActivityLog.objects.filter(activity_time__lt=dt_2_months_ago).delete()

    response = self.get_response(request)
    return response

One note here, are you sure you want to be running this in middleware? It'll run on every single request, every time you get js, every ajax request etc. Just a thought.

  • I don't want the user to go to some specific view to delete the activity log so I write it in middleware.Is there any approach for this besides middleware ? – D_P Jun 23 '20 at 09:55
  • Couple of ways to do it. The best way would be to have a CronJob that runs periodically, every three hours for instance. Or overwrite the save method of your UserActivityLog model. – Tom Hamilton Stubber Jun 23 '20 at 13:07