9
votes

Django - Exécution d'une tâche par le céleri à partir d'un modèle

dans mes modèles.pyRY:

from celery.decorators import task
from core.models import Image

@task()
def create_thumbnail(image_id):
    ImageObj = Image.objects.get(id=image_id)
    # other stuff here
  • Type d'exception: strong> ImporterRor Li>
  • Valeur d'exception: strong> Impossible d'importer des tâches de noms li> ul>

    L'erreur disparaît si je commencez de core.models importer image image code> dans les tâches dans code>, cependant, cela entraînera évidemment un problème car Image code> n'a aucune signification ici. J'ai essayé de l'importer à l'intérieur de créer_thumbnail code> mais il ne reconnaîtra toujours pas image code>. P>

    J'ai lu quelque part que l'objet lui-même peut être passé. comme un argument à une tâche et cela résoudrait mon problème. Cependant, un ami m'a dit une fois que cela était considéré comme étant la meilleure pratique d'envoyer au moins de données que possible dans un message de rabbbitmq, afin de réaliser que j'essaie de ne transmettre que l'ID d'image, puis de la récupérer à nouveau dans la tâche. P>

    1) est ce que j'essaie de faire une meilleure pratique? Si oui, comment puis-je le faire? P>

    2) J'ai remarqué dans tous les exemples que j'ai trouvés sur le Web, ils exécutent la tâche à partir d'une vue et jamais d'un modèle. J'essaie de créer une vignette lorsque une nouvelle image est téléchargée, je ne veux pas appeler Create_Thumbnail dans chaque formulaire / vue que j'ai. Une idée à ce sujet? Exécute une tâche d'un modèle non recommandé ou une pratique courante? P> p>


0 commentaires

3 Réponses :


3
votes

Je me demande si le problème peut être une importation circulaire ( modèles et Importation les uns des autres au niveau supérieur). Essayez de déplacer " de core.models importer image " dans créer_thumbnail , i.e. Modification des tâches à xxx


7 commentaires

J'ai déjà essayé que, dans ce cas, le message est envoyé correctement, Create_Thumbnail génère une erreur: fichier "/home/tasks.project/core/tasks.py", ligne 5, dans create_thumbnail à partir de core.models Importation image nomError: Nom global "image" n'est pas défini


Je suppose noyau est le nom de votre application. Avez-vous essayé de préparer le nom du projet (c.-à-d. à partir du modèle d'importation de projet.app.Models )? Django fait une magie de chemin qui est parfois moins que utile


Juste, la même erreur renvoyée: NameError: Nom global 'image' n'est pas défini . J'ai déjà annexé mon chemin de projet dans django.wsgi .


Les seuls paramètres que j'ai pour le céleri sont les suivants dans paramètres.py : # Paramètres de célery Importation djceley djcelery.setup_loader () < / code> courtier_host = "localhost" broker_port = 5672 broker_user = "invité" courtier_password = "invité" < Code> courtier_vhost = "/" update : aussi les suivants dans django.wsgi : os.environ ["célery_loader '] =' Django '


Ok je viens de vérifier l'interface administrative et j'ai 0 travailleurs apparemment! Je ne sais pas si cela est pertinent cependant, comme je suis déjà en cours d'exécution au céleri dans un terminal et que vous pouvez voir les messages à traverser.


Êtes-vous certainement en cours d'exécution au célery de Django?


Oui: python gérer.py céleryd-verbosité = 2 --Loglevel = débogage



15
votes

1) est ce que j'essaie de faire considérer une meilleure pratique? Si oui, comment puis-je le faire? P>

Oui, n'abandonnez que quelques informations sur la tâche, c'est généralement une bonne chose comme vous l'avez mentionnée. P>

2) J'ai remarqué dans tous les exemples que j'ai trouvés autour du Web, ils exécutent la tâche d'une vue et jamais d'un modèle. J'essaie de créer une vignette lorsque une nouvelle image est téléchargée, je ne veux pas appeler Create_Thumbnail dans chaque formulaire / vue que j'ai. Une idée à ce sujet? Exécute une tâche d'un modèle non recommandé ou une pratique courante? P> BlockQuote>

J'ai remarqué la même chose, et sentez que les tutoriels et la documentation appellent des tâches d'appel de leurs points de vue car il est plus facile de démontrer comment les choses fonctionnent avec des vues simples qu'avec des modèles ou des formulaires. P>

Éliminer les importations circulaires, vous devriez penser à la manière dont les importations devraient arriver. En règle générale, les tâches devront importer de nombreuses choses à partir de modèles.py alors que les modèles.py a rarement besoin de savoir quoi que ce soit sur les tâches .Pary. La norme doit être que modèles.py n'importe pas de tâches .py. Ainsi, si vous avez besoin de le faire et appelez une tâche à partir d'une méthode de modèle, apportez l'importation dans la méthode comme suit: P>

from django.db import models

class Image(models.Model):
    image     = models.ImageField(upload_to='images/orig')
    thumbnail = models.ImageField(upload_to='images/thumbnails', editable=False)

    def save(self, *args, **kwargs):
       super(Image, self).save(*args, **kwargs)
       from core.tasks import create_thumbnail
       create_thumbnail.delay(self.id)

1 commentaires

J'apprécie vraiment le paragraphe "d'éliminer les importations circulaires, vous devriez penser à la manière dont les importations devraient se produire ...". Merci.



4
votes

Vous n'avez pas besoin d'importer la tâche elle-même. Essayez d'utiliser le suivant

from django.db import models
from celery.execute import send_task, delay_task

class Image(models.Model):
    image     = models.ImageField(upload_to='images/orig')
    thumbnail = models.ImageField(upload_to='images/thumbnails', editable=False)

    def save(self, *args, **kwargs):
       super(Image, self).save(*args, **kwargs)
       result = delay_task("task_prefix.create_thumbnail", post.id)


1 commentaires

célery.execute ne semble pas exister plus dans le céleri 3.x