# ========================
# LEGACY VERSION (OLD)
# ========================
def update_expired_participants_legacy(course_id: int):
"""
LEGACY implementation for updating expired participants.
This version uses jdatetime to handle Persian dates and loops
through all participants to check if their end date has passed.
It's functional but inefficient for large datasets.
"""
today = jdatetime.date.today() # Current Jalali date
# Get participants with a defined end date
participants_qs = Participants.objects.filter(course_id=course_id, endDay__isnull=False)
expired_ids = []
for p in participants_qs:
# Check if endDay has valid year/month/day
if p.endDay and p.endDay.month and p.endDay.month.year:
# Construct Jalali date from nested structure
end_date = jdatetime.date(
p.endDay.month.year.number,
p.endDay.month.number,
p.endDay.number
)
# If the end date is before today, mark as expired
if end_date < today:
expired_ids.append(p.id)
# Reset all participants to expired=False first
participants_qs.update(expired=False)
# Update expired=True for those who actually expired
if expired_ids:
Participants.objects.filter(id__in=expired_ids).update(expired=True)
# ========================
# MODERN VERSION (NEW)
# ========================
def update_expired_participants(course_id: int):
"""
MODERN implementation for updating expired participants.
This optimized version avoids looping by using direct database queries.
It uses the Gregorian date stored in `endDay__gregorian_date` to determine
expired participants.
"""
today = date.today() # Current Gregorian date
# Set expired=True for participants whose end date is before today
Participants.objects.filter(
course_id=course_id,
endDay__gregorian_date__lt=today
).update(expired=True)
# Set expired=False for participants whose end date is today or in the future
Participants.objects.filter(
course_id=course_id,
endDay__gregorian_date__gte=today
).update(expired=False)
# Optional: return counts for logging or monitoring
expired_count = Participants.objects.filter(course_id=course_id, expired=True).count()
active_count = Participants.objects.filter(course_id=course_id, expired=False).count()
return {"expired": expired_count, "active": active_count}
💡 نکته / تجربه شخصی:
همیشه برای آپدیت دستهجمعی، به جای حلقه زدن روی queryset، از کوئری مستقیم دیتابیس استفاده کنید. این روش عملکرد را بهبود میدهد، بار سرور را کم میکند و کد مقیاسپذیر و قابل نگهداری میسازد.
استفادهشده در پروژه: PowerGrow