Prakash Kumar
Prakash Kumar

Reputation: 2594

How to make cron time editable for django admin

I have to allow the admin the set the cron time from admin view in django. Like i have an configuration model , where admin can put the time as record

  1. 2 am (record 1)
  2. 4 pm (record 2)

So on each record i have to run the cron. But cron time is in setting.py

CRONJOBS = [
    ('*/5 * * * *', 'myapp.cron.my_scheduled_job')
]

https://pypi.org/project/django-crontab/

How to make this setting available for admin.

Upvotes: 0

Views: 915

Answers (1)

r_black
r_black

Reputation: 634

I don't see any nice way of doing it, because vanilla django_crontab allows populating crontab only from settings. You'd better find other package that allows what you want. But if you have no choice, I think the following will work:

my_crontab.py

from django_crontab.app_settings import Settings
from django_crontab.crontab import Crontab
from django.conf import settings

# function need to return crontab
# in the same format as settings.py
def populate_from_db():
    # some db magic
    return [('*/5 * * * *', 'myapp.cron.my_scheduled_job')]


class DBCronSettings(Settings):

    def __init__(self, settings):
        super().__init__(settings)
        self.CRONJOBS = populate_from_db() #


class DBCrontab(Crontab):

    def __init__(self, **options):
        super().__init__(**options)
        self.settings = DBCronSettings(settings)

You need to subclass Crontab and Settings. Make DBCronSettings read your cron jobs from database and then use this settings in your custom DBCrontab.

Then make your own crontab command. Handle method exactly the same as in base command, but uses your DBCrontab class instead of original.

command.py

from django_crontab.management.commands.crontab import Command as CrontabCommand
from my_crontab import DBCrontab as Crontab


class Command(CrontabCommand):

    def handle(self, *args, **options):
        """
        Dispatches by given subcommand
        """
        if options['subcommand'] == 'add':         # add command
            with Crontab(**options) as crontab:    # initialize a Crontab class with any specified options
                crontab.remove_jobs()              # remove all jobs specified in settings from the crontab
                crontab.add_jobs()                 # and add them back
        elif options['subcommand'] == 'show':      # show command
            # initialize a readonly Crontab class with any specified options
            with Crontab(readonly=True, **options) as crontab:
                crontab.show_jobs()                # list all currently active jobs from crontab
        elif options['subcommand'] == 'remove':    # remove command
            with Crontab(**options) as crontab:    # initialize a Crontab class with any specified options
                crontab.remove_jobs()              # remove all jobs specified in settings from the crontab
        elif options['subcommand'] == 'run':       # run command
            Crontab().run_job(options['jobhash'])  # run the job with the specified hash
        else:
            # output the help string if the user entered something not specified above
            print(self.help)

Also don't forget to remove django_crontab from INSTALLED_APPS if you plan to name your command 'crontab'.

Upvotes: 1

Related Questions