定期调用django函数

时间:2018-11-30 06:37:28

标签: django amazon-web-services

这是有关Web开发的新手问题。我正在尝试为开发人员找到一种安全,更好的方法,以调用并运行一个功能,该功能可以从django应用程序中发送电子邮件,使他们可以手动覆盖和发送邮件,也可以对其进行时间激活,从而定期在固定时间发送电子邮件。一周。

我找到了答案,提示在Running a function periodically in Django上使用芹菜

但是我想更改周期而不重新部署我的应用程序。我已经对aws工具进行了一些研究,我认为AWS网关和aws lambda和aws cloudwatch结合使用可以将url /端点(或获取请求)发送到我的Web应用程序以激活该功能。

此刻我有类似下面的内容。

views.py

def api_send_email(request):

    #insert send email function
    print ("sending")

    return redirect('/')

urls.py

urlpatterns = [
    url(r'^send_email$', api_send_email, name="api_send_email"),
]

因此,可以通过转到URL https // xxx / send_email手动触发上述操作,也可以通过从AWS定期向该URL发送获取请求来触发上述操作。我曾经考虑过要进行发布请求,这将使请求更加安全,但是我不确定aws工具是否可以做到这一点,因为它需要在我的应用程序本身中添加csrf令牌。

欢迎提出最佳的方法建议。

谢谢

1 个答案:

答案 0 :(得分:1)

我想您也可以用芹菜来做到这一点。为此,您可以添加定期任务。假设您有一个定期任务,每5分钟启动一次。

然后,您可以在模型中使用自己的逻辑,以确定当时是否应该通过电子邮件发送电子邮件。例如:

class YourTaskConfig(models.Model):
    SEND_CHOICES = (
        ('minute': 'minute'),
        ('hour': 'hour'),
        ('day': 'day'),
    )
    send_every = models.CharField(max_length=25, choices=SEND_CHOICES)
    interval_amount = models.IntegerField()
    last_executed = models.DateTimeField(auto_add_now=True)
    is_active = models.BooleanField(default=True)

    def should_run(self):
       now = timezone.now()
       if self.send_every == 'minute':
           td = datetime.timedelta(seconds=self.interval_amount*60)
       elif self.send_every == 'day':
           td = datetime.timedelta(days=self.interval_amount)
       ... # rest of the logic on time delta
       if now - self.last_executed >= td:
           self.save()  # Updates current execution time
           return True
       return False

您的电子邮件模型可以对此配置使用FK(如果有):

class Email(models):
    config = models.ForeignKey(YourTaskConfig, on_delete=models.DO_NOTHING)

并使用它的定期任务:

from celery.task.schedules import crontab
from celery.decorators import periodic_task


@periodic_task(run_every=(crontab(minute='*/5')), name="some_task", ignore_result=True)  # Runs every 5 minute
def some_task():
    for i in YourTaskConfig.objects.filter(is_active=True):  # run only active tasks
        should_send_email = i.should_run()
        if should_send_email:
            i.email_set.all()  # Here you go, you have your emails which you want send

FYI:它是未经测试的代码,但是您可以了解此解决方案的总体思路。希望对您有帮助!