【发布时间】:2019-04-10 05:51:27
【问题描述】:
我在 Django REST 框架的序列化程序中重写了 update 方法。
在这个update,由于用户可以发送很多孩子,我有一个异步芹菜任务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(或 pickle、yaml 等)args。
- 但这个设置似乎有效
- 我什至可以发送
datetime对象(即我在任务中使用的start属性,以将存储的子对象与通过 api 发送的新值进行匹配)。
那么这里发生了什么?
- 一切正常吗,celery 像老大一样序列化和反序列化 OrderedDict。
- 还是我疯了,应该在调用任务之前序列化并在任务内部反序列化?
[更新,添加 CELERY 设置]
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'
【问题讨论】:
-
您是否尝试过
dict(children_data),以便在发送到任务之前将其转换为普通字典? -
使用
dict会比使用OrderedDict更好吗?现在有什么意义,一切似乎都在测试和生产中工作?我的问题更多是正确还是我应该在json中对自己进行序列化和反序列化。
标签: django django-rest-framework celery django-celery ordereddict