上下文:
- 模型对象的 user_account_granted 帐户指示模型对象是否链接到非空用户帐户。
- 当 user_account_granted 从 False 更改为 True 时,我在重写的 save() 函数中检测到这一点。在这里,我成功创建了一个用户,从模型对象中提取参数(电子邮件、用户名、姓名等)
- 我创建密码并将新帐户登录信息发送到对象的电子邮件
- 如果电子邮件发送失败,我会删除该帐户
问题:
我想提醒当前用户(刚刚提交了触发 save() 的表单)电子邮件要么成功(并且新帐户现在存在),要么不成功(并且没有创建新帐户)。我无法在 save() 函数中使用 Django 消息传递框架,因为它需要请求。我能做什么?
def save(self, *args, **kwargs):
if self.id:
previous_fields = MyModel(pk=self.id)
if previous_fields.user_account_granted != self.user_account_granted:
title = "Here's your account!"
if previous_fields.user_account_granted == False and self.user_account_granted == True:
user = User(
username=self.first_name + "." + self.last_name,
email=self.email,
first_name=self.first_name,
last_name=self.last_name
)
random_password = User.objects.make_random_password() #this gets hashed on user create
user.set_password(random_password)
user.save()
self.user = user
message = "You have just been given an account! \n\n Here's your account info: \nemail: " + self.user.email + "\npassword: " + random_password
if previous_fields.user_account_granted == True and self.user_account_granted == False:
message = "You no longer have an account. Sorry :( "
try:
sent_success = send_mail(title, message, 'example@email.com', [self.email], fail_silently=False)
if sent_success == 1:
##HERE I WANT TO INDICATE EMAIL SENT SUCCESS TO THE USER'S VIEW AFTER THE FORM IS SUBMITTED
else:
##HERE I WANT TO INDICATE EMAIL SENT FAILURE TO THE USER'S VIEW AFTER THE FORM IS SUBMITTED
user.delete()
self.user_account_granted = False
except:
##HERE I WANT TO INDICATE EMAIL SENT FAILURE TO THE USER'S VIEW AFTER THE FORM IS SUBMITTED
user.delete()
self.user_account_granted = False
super(MyModel, self).save(*args, **kwargs)
最佳答案
您不会在模型的 save()
函数中发送电子邮件。曾经。这不是它的目的。考虑:
save()
可以从 shell 调用。save()
可以从项目中的任何位置调用。
save()
方法的目的是保存对象。故事结束。
让我们仔细看看他们的目的是什么:
Form的基本作用是封装数据的输入和验证。它可以扩展以涵盖 Command 的全部角色。 。毕竟,它只错过了一个
execute()
函数。View 的基本作用是根据浏览器的请求(此处为表单的 POST)采取操作并触发结果的显示。
您可以选择其中之一。您的表单上可以有一个 execute()
方法,只需从您的 View 中调用该方法即可。或者,您可以让 View 在检查表单 is_valid() 后采取行动。我个人会选择用于实际操作的表单,以及用于显示结果的 View 。
因此,在我看来,我将自定义 form_valid()
方法来调用 execute()
并根据结果执行所需的操作。即:
class MyForm(Form):
# whatever you already have there
def clean(self):
# unrelated to your issue, but just reminding you
# this is the place you make sure everything is right
# This very method MUST raise an error if any input or any
# other condition already known at that point is not fulfilled.
if you_do_not_want_to_grand_an_account:
raise ValidationError('Account not granted, because.')
return self.cleaned_data
def execute(self):
do_whatever()
needs_to_be_done()
if it_failed:
raise AnAppropriateError(_('Descriptive message'))
class MyView(FormView):
form = MyForm
# your other view stuff here
def form_valid(self, form):
try:
form.execute()
except AnAppropriateError as err:
messages.add_message(self.request, messages.ERROR, err.message)
else:
messages.add_message(self.request, messages.INFO, _('It worked'))
AnAppropriateError
如果您希望它快速而肮脏,则可能只是 RuntimeError
,但您应该定义自己的异常类。
此外,您可能需要使用 execute()̀ 方法装饰
@transaction.atomic()`,具体取决于其内容。
最后一点,请记住您无法确定电子邮件是否确实已发送。即使存在一些错误,邮件系统也会接受电子邮件,这是很常见的。几天后,您只会知道它何时反弹。
关于python - 如何从 Django 模型(覆盖) save( ) 函数向 View 发送警报或消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30878333/