如何将 Django 对象发送到芹菜任务?
How to send django objects to celery tasks?
大家好!
在我提出问题之前,我尝试了这些 SO 帖子:
- Pass parameter request to a celery task in Django
None 个有效!
我想让用户在网站上更新新课程。使用 Courses
的查询集,我想通过电子邮件发送它们。
send_daemon_email.delay(instance=instance,all_courses=Course.objects.all())
我的函数如下所示:
@shared_task
def send_daemon_email(instance,all_courses):
ctx = {'instance':instance,'all_courses':all_courses}
message = get_template("emails/ads.html").render(ctx)
''' '''
当我尝试将电子邮件发送给特定用户时
我得到的错误是
<User: First Name> is not JSON serializable
只是因为delay()
从celery中得到了一个非序列化的数据。
如何将 Django 对象发送到 celery 任务以便在模板中使用它?我知道我可以将需要的信息发送为 python object
send_daemon_email.delay(first_name='Name',
last_name='Lapr',all_courses = [{'title1':'title1',},{'title2':'title2',}])
但是信息太多了。
如有任何提示,我们将不胜感激。
谢谢!
通常像 celery 这样的工具使用 格式 来传递消息。这里使用了 JSON,并不是每个 Python 对象都可以默认变成 JSON 对象。
但是,我们可以传递主键,然后在接收方再次将它们转换为对象。例如:
send_daemon_email.delay(
instance=<b>instance.pk</b>,
all_courses=<b>list(</b>Course.objects.all()<b>.values_list('pk', flat=True))</b>
)
然后在接收器端,我们可以使用以下方法获取对象:
@shared_task
def send_daemon_email(instance,all_courses):
ctx = {
'instance': <b>User.objects.get(pk=instance)</b>,
'all_courses': <b>Course.objects.filter(pk__in=all_courses)</b>
}
message = get_template("emails/ads.html").render(ctx)
当然我们本身不需要传递主键:任何类型的可以JSON序列化(或手动序列化)的对象都可以使用.虽然我不会让它太复杂,但通常简单的事情比复杂的事情更好(这是 Python 的 credos 之一)。
Django 对象无法在 celery 任务中发送,您可以使用 Django 序列化程序 (from django.core import serializers
) 序列化,方法是提供模板中所需的字段,查找将起作用就像模板中的 django 对象
NOTE: with serializer you will need to dump and load the data
或者只是将您的查询集转换为如下列表:
send_daemon_email.delay(
instance = User.objects.filter(pk=user.pk).values('first_name','last_name'),
all_courses= list(Course.objects.values('title','other_field'))
)
您只需在模板中提供您真正需要的字段 values('')
@shared_task
def send_daemon_email(instance,all_courses):
ctx = {
'instance': instance,
'all_courses': all_courses,
}
message = get_template("emails/ads.html").render(ctx)
在模板中{% for course in all_courses %}{{course}}{% endfor %}
将显示所有课程,{{ instance.first_name }}
用户
大家好!
在我提出问题之前,我尝试了这些 SO 帖子:
- Pass parameter request to a celery task in Django
None 个有效!
我想让用户在网站上更新新课程。使用 Courses
的查询集,我想通过电子邮件发送它们。
send_daemon_email.delay(instance=instance,all_courses=Course.objects.all())
我的函数如下所示:
@shared_task
def send_daemon_email(instance,all_courses):
ctx = {'instance':instance,'all_courses':all_courses}
message = get_template("emails/ads.html").render(ctx)
''' '''
当我尝试将电子邮件发送给特定用户时 我得到的错误是
<User: First Name> is not JSON serializable
只是因为delay()
从celery中得到了一个非序列化的数据。
如何将 Django 对象发送到 celery 任务以便在模板中使用它?我知道我可以将需要的信息发送为 python object
send_daemon_email.delay(first_name='Name',
last_name='Lapr',all_courses = [{'title1':'title1',},{'title2':'title2',}])
但是信息太多了。
如有任何提示,我们将不胜感激。 谢谢!
通常像 celery 这样的工具使用 格式 来传递消息。这里使用了 JSON,并不是每个 Python 对象都可以默认变成 JSON 对象。
但是,我们可以传递主键,然后在接收方再次将它们转换为对象。例如:
send_daemon_email.delay(
instance=<b>instance.pk</b>,
all_courses=<b>list(</b>Course.objects.all()<b>.values_list('pk', flat=True))</b>
)
然后在接收器端,我们可以使用以下方法获取对象:
@shared_task
def send_daemon_email(instance,all_courses):
ctx = {
'instance': <b>User.objects.get(pk=instance)</b>,
'all_courses': <b>Course.objects.filter(pk__in=all_courses)</b>
}
message = get_template("emails/ads.html").render(ctx)
当然我们本身不需要传递主键:任何类型的可以JSON序列化(或手动序列化)的对象都可以使用.虽然我不会让它太复杂,但通常简单的事情比复杂的事情更好(这是 Python 的 credos 之一)。
Django 对象无法在 celery 任务中发送,您可以使用 Django 序列化程序 (from django.core import serializers
) 序列化,方法是提供模板中所需的字段,查找将起作用就像模板中的 django 对象
NOTE: with serializer you will need to dump and load the data
或者只是将您的查询集转换为如下列表:
send_daemon_email.delay(
instance = User.objects.filter(pk=user.pk).values('first_name','last_name'),
all_courses= list(Course.objects.values('title','other_field'))
)
您只需在模板中提供您真正需要的字段 values('')
@shared_task
def send_daemon_email(instance,all_courses):
ctx = {
'instance': instance,
'all_courses': all_courses,
}
message = get_template("emails/ads.html").render(ctx)
在模板中{% for course in all_courses %}{{course}}{% endfor %}
将显示所有课程,{{ instance.first_name }}
用户