2

I am now making a website where teachers announce assignments and students submit them. I made boards that they can post their announcements or submission but do not know how to check those who did not submit their homework. I want some functions that run automatically at the designated time (in this case, on the due date of the assignment, the function judges and gathers who did not get their homework done)

I looked for some libraries related to datetime but have no idea.

assignments/models.py

class Assignment(models.Model):
    group = models.ForeignKey(Group, on_delete=models.CASCADE)
    index_in_group = models.IntegerField()
    title = models.CharField(max_length=30, verbose_name='name')
    content = models.TextField(verbose_name=content')
    due_date = models.DateTimeField(verbose_name='due')
    created_at = models.DateTimeField(auto_now_add=True)

class Done(models.Model):
    assignment = models.ForeignKey(Assignment, on_delete=models.CASCADE)
    index_in_assignment = models.IntegerField()
    author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    done_img = models.ImageField(upload_to='AssignmentsDone')
    injung = models.IntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)

The function would be like this: (not the exact one - just memo)

def check_submission(request, assignment_id):  
    members = Members of the group (I will retrieve this thoroughly when actually code)
    submissions = Done.objects.filter(assignment.id = assignment_id)
    did_hw = [x.author for x in submissions]
    for member in members:
        if member not in did_hw:
            mark as unsubmitter

This post got too long.. but the question is actually so simple. I just wanna know if there is a way I can make a function work at a certain designated time user inputs.

Sanip
  • 1,772
  • 1
  • 14
  • 29
SSS
  • 35
  • 3
  • 1
    I think the most popular method of handling task queues is to use celery - https://docs.celeryproject.org/en/latest/. – michjnich Aug 13 '19 at 08:59
  • 1
    you should probably look into adding a CRON job. Like this: https://stackoverflow.com/questions/373335/how-do-i-get-a-cron-like-scheduler-in-python – prp Aug 13 '19 at 09:00

4 Answers4

2

You can use celery with Django:

Celery

Then if you have a function like this:

@shared_task
def add(x, y):
    return x + y

You will have access to it on your admin panel and you can schedule a time for it to run.

There will be few ways to run a task:

1 - Run a task in an interval. (every 10 seconds for example)

2 - Delay a task. (task_function.delay())

3 - Scheduling to run a task at a certain time.

Note: you will need celery beat for periodic tasks: celery/django-celery-beat

In your case, you can create a function that checks all assignments then run this function every 5 minutes or if the due dates are all fixed, just run the function on a certain time.

Navid Zarepak
  • 4,148
  • 1
  • 12
  • 26
0

You can use

https://pypi.org/project/django-crontab/ (All thing managed automatically)

OR

https://django-cron.readthedocs.io/en/latest/installation.html(Half Automatically, Half Manually)

OR

Even you use OS Cron to run a specific Django function. (Need to manged Manually)

Jamin
  • 133
  • 12
0

An alternative scheduling utility is the Advanced Python Scheduler: apscheduler

You can schedule a task; or multiple tasks, to run every interval or on CRON like commands

From their examples

from datetime import datetime
import os

from apscheduler.schedulers.blocking import BlockingScheduler


def tick():
    print('Tick! The time is: %s' % datetime.now())


if __name__ == '__main__':
    scheduler = BlockingScheduler()
    scheduler.add_job(tick, 'interval', seconds=3)
    print('Press Ctrl+{0} to exit'.format('Break' if os.name == 'nt' else 'C'))

    try:
        scheduler.start()
    except (KeyboardInterrupt, SystemExit):
        pass
Lucan
  • 2,907
  • 2
  • 16
  • 30
0

here is a vanilla way

Doc is there : http://docs.python.org/py3k/library/sched.html

from datetime import datetime
now = datetime.now()


from datetime import timedelta
run_at = now + timedelta(hours=3)
delay = (run_at - now).total_seconds()

You can then usethreading.Timer :

threading.Timer(delay, self.update).start()