【发布时间】:2019-03-18 09:00:55
【问题描述】:
要更新的实例有instance.email=abc@mail.com。
要更新或更改为xyz@mail.com的电子邮件
UserUpdateSerializer的更新方法。
def update(self, instance, validated_data):
email_updated=False
email = self.validated_data["email"]
print(instance.email) #abc@email.com
if email!=instance.email:
if User.objects.filter(email=email).exists():
raise serializers.ValidationError("email is not available")
else:
email_updated=True
instance.__dict__.update(**validated_data)
instance.save() # instance is saved.
print(instance.email) #xyz@email.com
if email_updated:
task_send_activation_mail.delay(instance.id)#this one here
print(instance.email) #xyz@email.com
return instance
当给方法一个 user_id 时,我正在使用 celery 向用户发送电子邮件:
from `celery` import shared_task
@shared_task
def send_activation_mail(user_id):
from project.models import User
user = User.objects.get(pk=user_id)
subject = 'Activate Your '+DOMAIN_SHORT_NAME+' Account'
message = get_template('registration/account_activation_email.html').render({
'domain_url': DOMAIN_URL,
'domain': DOMAIN,
'domain_short_name': DOMAIN_SHORT_NAME,
'domain_full_name': DOMAIN_FULL_NAME,
'domain_email': DOMAIN_EMAIL,
'domain_support_email': DOMAIN_SUPPORT_EMAIL,
'domain_support_url': DOMAIN_SUPPORT_URL,
'mobile_support': MOBILE_SUPPORT,
'user': user,
'uid': urlsafe_base64_encode(force_bytes(user.pk)).decode(),
'token': account_activation_token.make_token(user),
})
user.email_user(subject, DOMAIN_FULL_NAME +' ', html_message=message)
return user.email #"abc@email.com" is printed as celery output.
实例用instance.save()保存,其中email从abc@mail.com更新为xyz@mail.com,然后实例的id作为参数传递给shared_task方法以发送邮件。但认为电子邮件似乎终于更新了。从send_activation_mail(user_id):内部的user_id获取的User实例似乎没有更新,邮件发送到之前的email。
【问题讨论】:
-
每次在打印电子邮件值之前使用
instance.refresh_from_db(),因为目前您没有检查电子邮件是否保存到数据库,您只需在模型实例上打印缓存的电子邮件 -
@KamilNiski 是正确的。即使您可以将 instance.email 传递给 send_activation_mail() 方法,而不是查询 shared_task
-
@KamilNiski 是的。该实例似乎尚未保存到数据库。调用保存后如何强制它立即保存?在整个
update方法执行之后,实例已经被保存。但不是instance.save(0 -
@Shameless 看起来您的问题不在您提供的代码中。我怀疑
instance.__dict__.update(**validated_data)会导致错误。现在我建议粘贴settings.py并使用ipdb和手动调试。可能我们没有足够的信息来解决这个问题。
标签: django django-rest-framework celery