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

时间:2017-10-17 14:23:05

标签: python django celery

我目前正在我的某个模型中编辑保存方法,以便我可以保存更改对象或创建新对象的人。

目前,它在主线程中运行时工作正常,但是save方法也通过Celery在不同的任务中使用。当在任务None中运行save方法时,返回 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() 。为了让用户我正在使用django-curser,因为这个模型正在我的Django项目中的不同应用程序中使用。

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

我的保存方法是:

Execution failed for task ':woh:crashlyticsGenerateSymbolsRelease'.
> GC overhead limit exceeded

感谢。

1 个答案:

答案 0 :(得分:1)

装饰器解决方案:

我认为您可以使用此装饰器在芹菜任务中添加用户

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__

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

您可以使用相同的想法将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