Python 在模型保存时调用芹菜任务的位置

Python 在模型保存时调用芹菜任务的位置,python,django,celery,Python,Django,Celery,保存模型时,我需要调用芹菜任务。我有冲突的导入,我不知道如何解决。我想知道是否有人知道我可以用另一种方法来构造它,以避免相互冲突的导入 models.py from .tasks import celery_task class Picture(PolymorphicModel): file = models.ImageField() processed_file = models.ImageField(blank=True, null=True) ... de

保存模型时,我需要调用芹菜任务。我有冲突的导入,我不知道如何解决。我想知道是否有人知道我可以用另一种方法来构造它,以避免相互冲突的导入

models.py
from .tasks import celery_task

class Picture(PolymorphicModel):
    file = models.ImageField()
    processed_file = models.ImageField(blank=True, null=True)
    ...
    def save(self, *args, **kwargs):
        if self.file:
            self.processed_file = celery_task.delay(self.id, other_arg)
        super(Picture, self).save(*args, **kwargs)




tasks.py
from .models import Picture

@task
def celery_task(id, other_arg):
    try:
        picture = Picture.objects.get(id=id)
    except ObjectDoesNotExist:
        picture = None

    if picture:
        return some_other_function(picture.file)

    return None

请注意,您调用任务并期望它工作的方式存在问题,但这超出了您的问题范围。要修复循环导入,只需使用本地导入而不是全局导入:


models.py

class Picture(PolymorphicModel): file = models.ImageField() processed_file = models.ImageField(blank=True, null=True) ... def save(self, *args, **kwargs): from .tasks import celery_task if self.file: self.processed_file = celery_task.delay(self.id, other_arg) super(Picture, self).save(*args, **kwargs)
tasks.py
from .models import Picture @task def celery_task(id, other_arg): try: picture = Picture.objects.get(id=id) except ObjectDoesNotExist: picture = None if picture: return some_other_function(picture.file) return None

models.py

班级图片(多态模型): file=models.ImageField() 已处理的_file=models.ImageField(空白=True,空=True) ... def保存(自身、*args、**kwargs): from.tasks导入芹菜任务 如果self.file: self.processed_file=celery_task.delay(self.id,other_arg) 超级(图片,自我)。保存(*args,**kwargs)
tasks.py
从。模型导入图片 @任务 def芹菜任务(id,其他参数): 尝试: picture=picture.objects.get(id=id) 除ObjectDoesNotExist外: 图片=无 如果图片: 返回其他函数(picture.file) 一无所获
请注意,您调用任务并期望它工作的方式存在问题,但这超出了您的问题范围。要修复循环导入,只需使用本地导入而不是全局导入:


models.py

class Picture(PolymorphicModel): file = models.ImageField() processed_file = models.ImageField(blank=True, null=True) ... def save(self, *args, **kwargs): from .tasks import celery_task if self.file: self.processed_file = celery_task.delay(self.id, other_arg) super(Picture, self).save(*args, **kwargs)
tasks.py
from .models import Picture @task def celery_task(id, other_arg): try: picture = Picture.objects.get(id=id) except ObjectDoesNotExist: picture = None if picture: return some_other_function(picture.file) return None

models.py

班级图片(多态模型): file=models.ImageField() 已处理的_file=models.ImageField(空白=True,空=True) ... def保存(自身、*args、**kwargs): from.tasks导入芹菜任务 如果self.file: self.processed_file=celery_task.delay(self.id,other_arg) 超级(图片,自我)。保存(*args,**kwargs)
tasks.py
从。模型导入图片 @任务 def芹菜任务(id,其他参数): 尝试: picture=picture.objects.get(id=id) 除ObjectDoesNotExist外: 图片=无 如果图片: 返回其他函数(picture.file) 一无所获
为了补充2ps的答案,使用此代码结构,您将遇到数据库竞争条件。我发现这篇文章对解决这些问题特别有用

当两个或多个并发线程试图同时访问同一内存地址(或者在本例中,数据库中的某些特定数据)时,就会发生数据争用情况

这意味着Django应用程序和芹菜应用程序线程试图同时访问Picture实例。这篇文章指出了解决这个问题的三种方法,但对我有效的方法是使用
transaction.on\u commit(lambda:your\u cellery\u task.delay())

在您的情况下,这将是:

models.py
from .tasks import celery_task
from django.db import transaction

class Picture(PolymorphicModel):
    file = models.ImageField()
    processed_file = models.ImageField(blank=True, null=True)
    ...
    def save(self, *args, **kwargs):
        super(Picture, self).save(*args, **kwargs)
        if self.file:
            transaction.on_commit(lambda: celery_task.delay(self.id))


为了补充2ps的答案,使用此代码结构,您将遇到数据库竞争条件。我发现这篇文章对解决这些问题特别有用

当两个或多个并发线程试图同时访问同一内存地址(或者在本例中,数据库中的某些特定数据)时,就会发生数据争用情况

这意味着Django应用程序和芹菜应用程序线程试图同时访问Picture实例。这篇文章指出了解决这个问题的三种方法,但对我有效的方法是使用
transaction.on\u commit(lambda:your\u cellery\u task.delay())

在您的情况下,这将是:

models.py
from .tasks import celery_task
from django.db import transaction

class Picture(PolymorphicModel):
    file = models.ImageField()
    processed_file = models.ImageField(blank=True, null=True)
    ...
    def save(self, *args, **kwargs):
        super(Picture, self).save(*args, **kwargs)
        if self.file:
            transaction.on_commit(lambda: celery_task.delay(self.id))


这完全解决了我的一个问题,使用芹菜的post_保存信号。当我保存在admin中时,从芹菜调用的函数将抛出DoesNotExist,但当我调试并逐步完成时,一切都很好。非常感谢。这完全解决了我的一个问题,使用芹菜的post_保存信号。当我保存在admin中时,从芹菜调用的函数将抛出DoesNotExist,但当我调试并逐步完成时,一切都很好。非常感谢。