Django Rest Framework更新方法在序列化程序中,实例不会立即保存

编程入门 行业动态 更新时间:2024-10-27 06:20:09
本文介绍了Django Rest Framework更新方法在序列化程序中,实例不会立即保存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

要更新的实例具有 instance.email=abc@mail 。

要发送的电子邮件已更新或更改为 xyz@mail

email to be updated or changed to xyz@mail

UserUpdateSerializer 的更新方法。

def update(self, instance, validated_data): email_updated=False email = self.validated_data["email"] print(instance.email) #abc@email 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 if email_updated: task_send_activation_mail.delay(instance.id)#this one here print(instance.email) #xyz@email return instance

我正在使用芹菜向其发送电子邮件用户,当为该方法赋予user_id时:

I am using celery to send an email to the user when given a user_id to the method as:

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" is printed as celery output.

实例通过 instance.save(),其中电子邮件从 abc@mail 更新为 xyz @ mail。 com ,然后实例的ID作为参数传递给 shared_task 方法以发送邮件。但是以为电子邮件似乎终于更新了。从 send_activation_mail(user_id)内的 user_id 获得的 User 实例:似乎尚未更新,并且邮件已发送到以前的电子邮件。

The instance is saved with instance.save(), where email is updated from abc@mail to xyz@mailand then the instance's id is passed as a parameter to a shared_task method to send a mail. But thought the email appears updated finally. The User instance obtained from the user_id inside the send_activation_mail(user_id): appears to have not updated and the mail is sent to the previous email.

推荐答案

instance.save()尚未提交到数据库。在此之前,调用了celery任务 send_activation_mail.delay(instance.id)导致获取的实例比所需的更新实例更早。

The instance.save() hasn't committed to the database yet. And before that the celery task send_activation_mail.delay(instance.id) has been called resulting in the getting the previous instance than the required updated instance.

因此,要克服这一点,我们应该使用 @ transaction.atomic 和 transaction.on_commit 即,

So to overcome this we should be using @transaction.atomic and transaction.on_commit i.e,

from django.db import transaction @transaction.atomic def myFunction(): user = User.objects.get(pk=1).update(email="xyz@email") transaction.on_commit(lambda: my_task.delay(user.pk))

@ transaction.atomic 装饰器将提交事务当视图返回时返回,或在视图引发异常时回滚。

@transaction.atomic decorator will commit the transaction when the view returns, or roll back if the view raises an exception.

transaction.on_commit 是在成功完成所有事务后启动任务的回调。

transaction.on_commit is a callback to launch a task once all transactions have been committed successfully.

on_commit 在Django 1.9及更高版本中可用

on_commit is available in Django 1.9 and above

更多推荐

Django Rest Framework更新方法在序列化程序中,实例不会立即保存

本文发布于:2023-10-10 01:14:43,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1477285.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:实例   序列化   程序   方法   Django

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!