【问题标题】:Passing objects through Django template to javascript通过Django模板将对象传递给javascript
【发布时间】:2015-09-17 21:09:13
【问题描述】:

我正在使用 Django 创建一个网站,我想通过 Django 模板从我的视图(创建它的位置)传递一个 python 对象并传递给 Dajax 调用。问题是当它进入 dajax 时,它已经变成了 unicode 类型。

在我的模板中

<script>
var emailer = "{{emailer|safe}}"; <---If I omit the quotes here then I get a javascript error.
sessionStorage.setItem('emailer',emailer);
$(document).ready(function(){

  $('.send').on('click', function(e){  
    var emailer = sessionStorage.getItem('emailer');

    Dajaxice.InterfaceApp.sendEmail(submitverify,{'emailer':emailer});
  });
});

</script>

dajax 函数

@dajaxice_register(method='GET')
def sendEmail(emailer):
    logger.warning("type: %s, %s" % (type(emailer),emailer))
    email_body = "message"
    emailer.addToMessage(email_body)
    emailer.send()

    message = "Email Sent"
return json.dumps({'message':message})

这里记录器语句返回:type: &lt;type 'unicode'&gt;, &lt;Utils.SIMPL_Emailer instance at 0x103142ab8&gt;。有什么办法可以解决这个问题,以便我得到我的电子邮件对象而不是 unicode 字符串?

【问题讨论】:

  • 等一下,您想将实际的序列化 Python 对象传递到您的模板中,然后通过 JavaScript 重新输入吗?这似乎非常不安全。你不能只传递最少的必要信息来在sendEmail 函数中重新创建电子邮件对象吗?

标签: javascript python django unicode


【解决方案1】:

首先尝试了解发生了什么:

在您的模板上,您正尝试将 Python 对象保存到 Javascript var:

var emailer = "{{emailer|safe}}";`

但这是不可能的。当您的模板由 Django 呈现时,您真正得到的是对 object __str__() 方法的调用,并且您的 Javascript 会将 值。请记住:此代码在客户端浏览器中运行。这就是为什么在删除引号时会出现错误。

要解决它,您需要首先序列化您的电子邮件对象(例如,将其转换为可以表示为字符串的东西,然后再转回 Python 对象)。但正如 Peter DeGlopper 所指出的,这是一种非常不安全的方法。永远不要反序列化可公开访问的整个对象。而是仅将电子邮件数据发送到您的模板。您可以使用此数据创建一个字典,将其转换为 JSON(它也是一个序列化,但这次您只序列化数据),然后将其传递给您的模板。

所以不要将您的电子邮件发送器放在模板上下文中。而是创建一个字典并将其传递给模板。

然后在您的 Python sendEmail(emailer) 方法中,您需要实例化一个新的 Emailer 对象并为其提供数据,例如:

@dajaxice_register(method='GET')
def sendEmail(email_json):
    email = json.loads(email_json) # email_json is a json with your email data only
    logger.warning("type: %s, %s" % (type(email_json),email_json))
    emailer = Emailer("<with all your params...>")
    emailer.addToMessage(email.get('body'))
    emailer.send()

    message = "Email Sent"
    return json.dumps({'message':message})

【讨论】:

  • 我想避免实例化新对象,因为当实例化对象时,许多与类运行相关的“后台”进程会减慢我的网站速度。我正在创建的网站将无法被公众访问(它将在私人服务器上),所以我不太担心。您将如何序列化一个对象,然后将其从字符串或 unicode 转换回对象?
  • 你可以使用pickle模块:link。但是有些对象是“不可拾取的”,例如套接字。而你的 Emailer 对象可能会陷入这个问题。
  • 我很确定没有办法使用序列化来避免实例化新实例的时间。序列化所做的只是提供了一种封装对象所有信息的方法。想一想 - 如果您保存了 HTML,重新启动计算机,然后再次解析序列化字符串,那么您显然是在创建一个新实例。同样,不能保证处理 Ajax 请求的线程与处理基本视图的线程相同。您需要重新考虑您的方法 - 可能通过不在视图中实例化电子邮件发送器,如果在 Ajax 请求之前实际上并不需要它。
猜你喜欢
  • 2013-05-20
  • 2011-08-17
  • 2013-02-09
  • 2013-09-15
  • 2013-10-09
  • 1970-01-01
  • 2018-12-03
  • 2011-01-31
  • 1970-01-01
相关资源
最近更新 更多