繁体   English   中英

使用django在芹菜中传递User对象

[英]Passing User object in celery using django

我正在编辑我的一个模型中的save方法,这样我就可以保存更改对象或创建新对象的人。

目前,它在主线程中运行时工作正常,但是save方法也通过Celery用于不同的任务。 当在任务中运行save方法时, get user返回None 为了得到一个用户我正在使用django-curser,因为这个模型正在我的Django项目中的不同应用程序中使用。

有没有办法将当前用户发送到芹菜? 我被告知使用上下文管理器或包装器,但我不知道如何。

我的保存方法是:

    def save(self, *args, **kwargs):
        from models import Log
        log_entry = Log()
        log_entry.object_id = self.id
        log_entry.object_repr = self
        user = CuserMiddleware.get_user()
        log_entry.user = user
        log_entry.content_type_id = ContentType.objects.get_for_model(self).id
        log_entry.save()

谢谢。

装饰解决方案:

我想你可以使用这个装饰器在celery任务中添加用户

from functools import wraps


def append_user(func):
    @wraps(func)
    def __wrapper__(*args, **kwargs):
        user_login = kwargs.pop('user_login')
        CuserMiddleware.set_user(user_login)
        return func(*args, **kwargs)
    return __wrapper__

并以这种方式应用于任务

@task
@append_user
def celery_job():
    pass

同样对于我的芹菜任务,我使用这个装饰器(关闭设置中的所有异步作业)

def async_task(func):
    from django.conf import settings
    ALL_TASKS_IS_ASYNC = getattr(settings, 'ALL_TASKS_IS_ASYNC', True)

    @wraps(func)
    def __wrapper__(*args, **kwargs):
        async = kwargs.pop('async', ALL_TASKS_IS_ASYNC)
        if async:
            return func.delay(*args, **kwargs)
        else:
            return func(*args, **kwargs)
    return __wrapper__

__init__.py文件中的celery_job = async_task(celery_job)

您可以使用相同的想法将user_login附加到所有任务

def async_task(func):
    from django.conf import settings
    ALL_TASKS_IS_ASYNC = getattr(settings, 'ALL_TASKS_IS_ASYNC', True)

    @wraps(func)
    def __wrapper__(*args, **kwargs):
        kwargs['user_login'] = CuserMiddleware.get_user().username
        async = kwargs.pop('async', ALL_TASKS_IS_ASYNC)
        if async:
            return func.delay(*args, **kwargs)
        else:
            return func(*args, **kwargs)
    return __wrapper__

编辑:

我认为这个装饰可能会优化重构:

def task_with_user_info(func):
    @wraps(func)
    def __wrapper__(*args, **kwargs):
        user = CuserMiddleware.get_user()
        kwargs['user_login'] = user.username
        return func(*args, **kwargs)
    if getattr(func, 'delay', None):
        __wrapper__.delay = task_with_user_info(func.delay)
    return __wrapper__


@task_with_user_info
@task
@append_user
def celery_job():
    pass

在此更改后,您应该像往常一样使用celery_job

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM