Python37 и Django 2 TextField не строка? - PullRequest
0 голосов
/ 04 июля 2018

Мы решили перенести наш проект django 1.10.5 с python 2.7.15 на более новую версию 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))

С этим он работает, но он позволяет моему животику болеть, когда я так делаю, поскольку я не понимаю, почему.

Edit:

    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)

Entry - это объект 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))

После этого мы извлекли наш текст и создали задачу сейчас:

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 ().

1 Ответ

0 голосов
/ 09 июля 2018

Благодаря Дэниелу Роузману я нашел проблему. Поскольку я беру полезную нагрузку из почты в виде байтов и никогда не преобразую ее в строку, она сохраняется как байты в БД. Как только я запрашиваю данные из базы данных, это байты, и я должен преобразовать их в строку, как мне это нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...