python - Python37 和 Django 2 TextField 不是字符串?
问题描述
我们决定将带有 python 2.7.15 的 django 1.10.5 项目迁移到更新版本的 python 和 django。现在我们使用 python 3.7 和 django 2。在我们的电子邮件发送脚本出现一些问题后,我发现了一些奇怪的东西。在发送自动邮件时,我们从数据库中的 TextField 中获取文本并将其插入到我们的邮件中。
content = content.replace('##ENTRY##', entry.text)
输入的文本字段是 django models.TextField。现在使用 python 37 它不允许我那样使用它。我必须将 entry.text 包装成 str() 演员表。但是 TextField 不应该是一个字符串吗?
content = content.replace('##ENTRY##', str(entry.text))
这样就可以了,但是这样做会让我的肚子受伤,因为我不明白为什么。
编辑:
def send_task_entry_new(entry):
content = Email.load_email_template('tasks.watcher.info.entry.new')
content = content.replace('##TAG##', entry.task.get_tag())
content = content.replace('##ENTRY##', entry.text)
content = content.replace('##SUBJECT##', entry.task.get_subject())
subject = entry.task.get_tag() + " " + entry.task.get_subject()
for watcher in entry.task.taskwatcher_set.all():
if watcher.user.last_login:
content = content.replace('##LINK##', settings.BASE_URL + entry.task.get_absolute_url())
# If User has never logged in (Dummy for external task user)
else:
content = content.replace('##LINK##', settings.BASE_URL + reverse('tasks_public', args=[watcher.token]))
Email.send(watcher.user.email, '', '', subject, content)
条目是一个 TaskEntry 对象,它在我创建任务后立即创建。TaskEntry 模型如下所示。至少 TaskEntry 的属性:
task = models.ForeignKey(Task, null=True, on_delete=models.SET_NULL)
creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
external = models.EmailField(null=True, blank=True)
text = models.TextField(verbose_name="Text")
date_created = models.DateTimeField(auto_now_add=True)
编辑流程:
电子邮件进来并得到处理:
text = get_decoded_email_body(response_part[1])
触发:
def get_decoded_email_body(message_body):
msg = email.message_from_bytes(message_body)
if msg.is_multipart():
# Walk through all parts of this email
for part in msg.walk():
# print "%s => %s" % (part.get_content_type(), part.get_content_charset())
charset = part.get_content_charset()
#TODO umstellung auf Python3 enfernen und testen
if part.get_payload(decode=True):
if part.get_content_type() == 'text/plain':
if charset:
return str(part.get_payload(decode=True), charset, 'ignore')
else:
return to_unicode(part.get_payload(decode=True))
if part.get_content_type() == 'text/html':
if charset:
return str(part.get_payload(decode=True), charset, 'ignore')
else:
return to_unicode(part.get_payload(decode=True))
return "Email has no text/plain or text/html part"
else:
return to_unicode(msg.get_payload(decode=True))
之后,我们提取了文本并创建了一个 now 任务:
user = User.objects.get_or_create(email=sender)[0]
task = Task.objects.create(subject=subject, creator=user)
task.create_entry(text, user) #Here it crashes
Email.send_task_operators_new_task(task, text, sender)
现在进入models.py,我们进入create_entry:
def create_entry(self, text, creator):
entry = TaskEntry()
entry.text = text
entry.task = self
entry.creator = creator
entry.save()
if creator:
TaskWatcher.objects.get_or_create(task=self, user=creator)
下一步是 .save() 方法:
def save(self, *args, **kwargs):
if self.pk == None:
created = True
else:
created = False
super(TaskEntry, self).save(*args, **kwargs)
if created:
# If this entry is the first one inform creator and owner if given
if self.task.taskentry_set.all().count() == 1:
Email.send_task_created_to_creator(self.task)
# If a owner has been given how is not the creator
if self.task.owner and self.task.owner != self.task.creator:
Email.send_task_created_to_owner(self.task)
# This is not the first entry, so inform all watcher about the new entry
if self.task.taskentry_set.all().count() > 1:
Email.send_task_entry_new(self)
现在它执行 Email.send_task_entry_new(self) 并抛出 replace() 错误。
解决方案
感谢 Daniel Roseman,我发现了这个问题。由于我将邮件中的有效负载作为字节获取并且从不将其转换为字符串,因此将其作为字节保存到数据库中。一旦我从数据库请求数据,它就是字节,我必须根据需要将它们转换为字符串。
推荐阅读
- install4j - install4j:“执行启动器”操作不适用于“需要管理员”执行级别
- r - 如何从一个数据框中的模式中获取另一个数据框?
- python - 具有第 i 个元素的 Torch 张量作为所有先前的乘积
- amazon-web-services - Terraform 嵌套 for_each aws_acm_certificate domain_validation_options
- python - 从复杂的多段落文档中提取单词并将其输出为多行逗号分隔文件
- r - 错误:无法加载外部实体“http://.......”
- swift - SwiftUI:拖入空列表时崩溃
- amazon-web-services - aws ec2 describe-instances 返回空数组
- angularjs - 如何避免在angularJs中从一个选项卡导航到另一个选项卡时多次触发$on?
- tensorflow - 与 model.predict 相比,Keras model.fit 非常非常慢