python - 如何从 Django 模型(覆盖) save( ) 函数向 View 发送警报或消息?

标签 python django model save message

上下文:

  1. 模型对象的 user_account_granted 帐户指示模型对象是否链接到非空用户帐户。
  2. 当 user_account_granted 从 False 更改为 True 时,我在重写的 save() 函数中检测到这一点。在这里,我成功创建了一个用户,从模型对象中提取参数(电子邮件、用户名、姓名等)
  3. 我创建密码并将新帐户登录信息发送到对象的电子邮件
  4. 如果电子邮件发送失败,我会删除该帐户

问题:

我想提醒当前用户(刚刚提交了触发 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() 方法的目的是保存对象。故事结束。

现在。让我们回到你真正想要实现的目标。您正在处理用户提交的表单。这意味着您至少在这里处理其他事情:表单和 View 。

让我们仔细看看他们的目的是什么:

  • 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/

相关文章:

python - 如何修复设置 Django 1.9 应用程序时无法序列化错误

php - Laravel 4 - 无法覆盖模型保存方法

python - 从 Django 中的表名中查找模型实例

python - DataFrame 在函数内部修改

python - 访问 Johnny 缓存数据

python - 使用 View 装饰器来处理用户权限是不好的做法吗?

swift - Realm 和 Swift - 为要更新的模型传递的参数

python - 我不能在 Django 项目中使用对象属性

python - 连接到在 boot2docker 中运行的 python 服务器时出错(centos 容器 | Windows 7.1 主机)

python - 另一个正则表达式问题