保存模型时,我需要调用芹菜任务。我有冲突的导入,我不知道如何解决。我想知道是否有人知道我可以构造这种方式以避免进口冲突
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
答案 0 :(得分:2)
请注意,您调用任务并期望其工作的方式存在问题,但这在您的问题范围之外。要修复循环导入,只需使用本地导入而不是全局导入即可:
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
答案 1 :(得分:1)
要补充2ps的答案,使用此代码结构将遇到数据库争用条件。我发现本文对解决他们https://www.vinta.com.br/blog/2016/database-concurrency-in-django-the-right-way/
特别有用当两个或多个并发线程尝试同时访问同一内存地址(或在这种情况下,是数据库中的某些特定数据)时,就会发生数据竞争情况。
这意味着Django应用程序和Celery应用程序线程尝试同时访问Picture实例。本文指出了三种解决方法,但是对我有用的一种方法是使用transaction.on_commit(lambda: your_celery_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))