le céleri tâche et de personnaliser décorateur

Je suis en train de travailler sur un projet à l'aide de django et de céleri(django-céleri). Notre équipe a décidé d'envelopper tout le code d'accès aux données à l'intérieur de (app-name)/manager.py(PAS envelopper dans les Gestionnaires comme les django façon), et laissez-code (app-name)/task.py seulement affaire avec les assembler et de les exécuter des tâches de céleri(si nous n'avons pas l'ORM de django dépendance dans cette couche).

Dans mon manager.py, j'ai quelque chose comme ceci:

def get_tag(tag_name):
    ctype = ContentType.objects.get_for_model(Photo)
    try:
        tag = Tag.objects.get(name=tag_name)
    except ObjectDoesNotExist:
        return Tag.objects.none()
    return tag

def get_tagged_photos(tag):
    ctype = ContentType.objects.get_for_model(Photo)
    return TaggedItem.objects.filter(content_type__pk=ctype.pk, tag__pk=tag.pk)

def get_tagged_photos_count(tag):
    return get_tagged_photos(tag).count()

Dans mon task.py, j'aime bien les envelopper dans des tâches (alors peut-être utiliser ces tâches à effectuer des tâches plus complexes), alors j'écris ce décorateur:

import manager #the module within same app containing data access functions

class mfunc_to_task(object):
    def __init__(mfunc_type='get'):
        self.mfunc_type = mfunc_type

    def __call__(self, f):
        def wrapper_f(*args, **kwargs):
            callback = kwargs.pop('callback', None)

            mfunc = getattr(manager, f.__name__)

            result = mfunc(*args, **kwargs)
            if callback:
                if self.mfunc_type == 'get':
                    subtask(callback).delay(result)
                elif self.mfunc_type == 'get_or_create':
                    subtask(callback).delay(result[0])
                else:
                    subtask(callback).delay()
            return result            

        return wrapper_f

ensuite (toujours dans task.py):

#@task
@mfunc_to_task()
def get_tag():
    pass

#@task
@mfunc_to_task()
def get_tagged_photos():
    pass

#@task
@mfunc_to_task()
def get_tagged_photos_count():
    pass

Les choses fonctionnent très bien sans @task.
Mais, après l'application de cette @task décorateur(vers le haut comme le céleri chargé de la documentation), les choses commencent à tomber en morceaux. Apparemment, chaque fois que le mfunc_to_task.__call__ est appelée, le même task.get_tag fonction reçoit comme f. Je me suis donc retrouvé avec le même wrapper_f tous les temps, et maintenant, la seule chose que je chat faire est d'obtenir une balise unique.

Je suis nouveau sur les décorateurs. Quelqu'un peut m'aider à comprendre ce qui s'est passé ici, ou point d'autres moyens pour réaliser la tâche? J'ai vraiment hate d'écrire la même tâche envelopper code pour chaque de mes fonctions d'accès aux données.

OriginalL'auteur zxygentoo | 2011-06-18