Celery Beat无法使用django-money更新货币汇率

mepcadol  于 2023-05-19  发布在  Go
关注(0)|答案(1)|浏览(175)

我使用django-money,然后我运行celery beat每60分钟更新一次货币汇率,代码如下。* 我关注了django-money doc:

# "core/celery.py"

import os

from celery import Celery

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings')

app = Celery('core')

app.config_from_object('django.conf:settings', namespace='CELERY')

app.autodiscover_tasks()

@app.task(bind=True)
def debug_task(self):
    print(f'Request: {self.request!r}')
# "core/tasks.py"

from celery import shared_task
from djmoney import settings
from django.utils.module_loading import import_string

@shared_task
def update_rates(backend=settings.EXCHANGE_BACKEND, **kwargs):
    backend = import_string(backend)()
    backend.update_rates(**kwargs)
    print("Successfully updated")
# "core/settings.py"

from celery.schedules import crontab

OPEN_EXCHANGE_RATES_APP_ID = '5507ba2d9b8f4c46adca3169aef9c281' # Here

CELERY_BEAT_SCHEDULE = {
    'update_rates': {
        'task': 'core.tasks.update_rates',
        'schedule': crontab(minute='*/60'),
        'kwargs': {}  # For custom arguments
    }
}

但是,即使我在settings.py中设置了OPEN_EXCHANGE_RATES_APP_ID,也会出现下面的错误:
django.core.exceptions.ImproperlyConfigured:设置。OPEN_EXCHANGE_RATES_APP_ID应设置为使用OpenExchangeRatesBackend
那么,我如何解决每60分钟用celery 跳动更新货币汇率的错误?

toe95027

toe950271#

您需要将OPEN_EXCHANGE_RATES_APP_ID传递给update_rates任务,其中'args'settings.py中,如下所示。* 实际上,在django-money doc中更新货币汇率的celery beat示例是旧的:

# "core/settings.py"

from celery.schedules import crontab

OPEN_EXCHANGE_RATES_APP_ID = '5507ba2d9b8f4c46adca3169aef9c281' # Here

CELERY_BEAT_SCHEDULE = {
    'update_rates': {
        'task': 'core.tasks.update_rates',
        'schedule': crontab(minute='*/60'),
        'args': [OPEN_EXCHANGE_RATES_APP_ID],
    }
}

然后,update_rates任务需要用app_id接收OPEN_EXCHANGE_RATES_APP_ID,然后将其分配给tasks.py中的access_key,如下图所示,然后可以解决错误,然后每60分钟更新一次货币汇率。* 您可以在GitHub上看到openexchangerates.py,以了解为什么OPEN_EXCHANGE_RATES_APP_ID需要分配给access_key

# "core/tasks.py"

from celery import shared_task
from djmoney import settings
from django.utils.module_loading import import_string

@shared_task     # Here
def update_rates(app_id):
    backend = import_string(settings.EXCHANGE_BACKEND)(
        access_key=app_id # Here
    )
    backend.update_rates()
    print("Successfully updated")

此外,OPEN_EXCHANGE_RATES_APP_ID可以在settings.py中的celery beat代码之后定义,如下所示,没有任何错误,我建议在celery beat代码之前导入crontab,如下所示,这样就不会发生错误:

# "core/settings.py"

from celery.schedules import crontab # Here

CELERY_BEAT_SCHEDULE = {
    'update_rates': {
        'task': 'core.tasks.update_rates',
        'schedule': crontab(minute='*/60'),
        'args': [OPEN_EXCHANGE_RATES_APP_ID],
    }
}

OPEN_EXCHANGE_RATES_APP_ID = '5507ba2d9b8f4c46adca3169aef9c281' # Here

并且,您可以在settings.py上使用新的celery beat代码,如下所示。* appupdate_rates任务需要分别从core/celery.pycore/tasks.py导入,如下所示,我建议在新的celery 节拍代码之前导入crontabappupdate_rates,如下所示,这样就不会发生错误:

# "core/settings.py"

from celery.schedules import crontab # Here
from .celery import app # Here
from .tasks import update_rates # Here

@app.on_after_configure.connect # Here
def setup_periodic_tasks(sender, **kwargs):
    sender.add_periodic_task(
        crontab(minute='*/1'),
        update_rates.s(OPEN_EXCHANGE_RATES_APP_ID), 
        name='update_rates'
    )

OPEN_EXCHANGE_RATES_APP_ID = '5507ba2d9b8f4c46adca3169aef9c281'

相关问题