我在Django REST Framework的序列化器中有一个被覆盖的update
方法。
在此update
中,由于用户可以发送很多孩子,所以我有异步Celery任务process_children
来处理孩子。
class MyModelSerializer(serializers.ModelSerializer):
....
@transaction.atomic
def update(self, mymodel, validated_data):
try:
children_data = validated_data.pop('children')
transaction.on_commit(lambda: process_children.apply_async(
countdown=1,
args=[mymodel.id, children_data]))
except KeyError:
pass
...
在args中,有一个参数不是json
对象而是OrderedDict
:children_data
。
任务如下:
@app.task
def process_children(mymodel_id, children_data):
mymodel = MyModel.objects.get(pk=mymodel_id)
children = mymodel.children.all()
for child_data in children_data:
try:
child = children.get(start=child_data['start'])
child = populate_child(child, child_data)
child.save()
except Child.DoesNotExist:
create_child(mymodel, child_data)
json
(或泡菜,yaml,等等...)参数。datetime
对象(即任务中使用的start
属性,以将存储的子对象与通过api发送的新值进行匹配)。CELERY_BROKER_URL = get_env_variable('REDIS_URL')
CELERY_BROKER_POOL_LIMIT = 0
CELERY_REDIS_MAX_CONNECTIONS = 10
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_TIMEZONE = 'Europe/London'
答案 0 :(得分:0)
您正在使用的pickle序列化器可以相对好地处理对象,但是存在一些顾虑。 Here's a blog post on the concept of serializing and celery.
答案 1 :(得分:0)
是的,您做得正确。
如doc中所述。
在客户端和工作人员之间传输的数据需要进行序列化,因此Celery中的每条消息都有一个content_type标头,用于描述用于对其进行编码的序列化方法。
此外,从celery 4.0开始,默认序列化器为JSON(之前pickle
)。因此,无论何时调用此任务,默认情况下celery都会对其进行序列化和反序列化。
如果要使用任何其他序列化程序,则在调用任务时,需要指定content-type
(如果使用.delay
,则默认情况下序列化程序为json
。
process_children.apply_async((model_id, children_data), serializer='pickle')