Ran some timeit tests on the two variants, for deleting a single item only on each pass.

My new way (with two queries), average time = 18.26139998435974s

Using the for loop, average time = 19.896235942840576s

Reran deleting five items on each pass:

My new way (with two queries), average time = 19.903857231140137s

Using the for loop, average time = 93.02654194831848

Conclusion? Bulk saves, even in single case.

Test script in case you wish to replicate (make sure to set USER_LOG_MAX_RECORDS = 10000 to prevent deletion of test logs).

from main.models import UserLog
from securesync.models import FacilityUser
import timeit
from datetime import datetime

sloop1 = """\
from main.models import UserLog
for user_log in UserLog.objects.order_by("start_datetime")[:1]:
    user_log.delete()
"""

sbulk1 = """\
from main.models import UserLog
to_discard = UserLog.objects.order_by("start_datetime")[:1]
UserLog.objects.filter(pk__in=to_discard).delete()
"""

sloop5 = """\
from main.models import UserLog
for user_log in UserLog.objects.order_by("start_datetime")[:5]:
    user_log.delete()
"""

sbulk5 = """\
from main.models import UserLog
to_discard = UserLog.objects.order_by("start_datetime")[:5]
UserLog.objects.filter(pk__in=to_discard).delete()
"""

for i in range(0, 1000):
    UserLog.begin_user_activity(user=FacilityUser.objects.all()[0], activity_type=1, start_datetime=datetime.now())

timeit.timeit(stmt=sloop1, number=100)

for i in range(0, 100):
    UserLog.begin_user_activity(user=FacilityUser.objects.all()[0], activity_type=1, start_datetime=datetime.now())

timeit.timeit(stmt=sbulk1, number=100)

for i in range(0, 100):
    UserLog.begin_user_activity(user=FacilityUser.objects.all()[0], activity_type=1, start_datetime=datetime.now())

timeit.timeit(stmt=sloop5, number=100)

for i in range(0, 500):
    UserLog.begin_user_activity(user=FacilityUser.objects.all()[0], activity_type=1, start_datetime=datetime.now())

timeit.timeit(stmt=sbulk5, number=100)