Відправлення електронних листів під час зміни електронної адреси

У моїй програмі DJango я хотів би реалізувати систему, щоб, коли поле email у моїй jmodel, MyModel змінювалося, на цю електронну адресу надсилається електронний лист. У мене є ModelForm на цій Моїй моделі. Як і як я повинен це реалізувати?

  1. Чи повинен я перевизначати метод save() мого ModelForm і надіслати його електронною поштою?
  2. Чи повинен я намагатися спробувати пастку певного оновленого сигналу моделі та надіслати електронний лист там, якщо так, то як? Який сигнал мене зачепив?

Який хороший спосіб перевірити, чи змінився електронний лист? Це саме те тривіальна річ, яку потрібно реалізувати, але я хотів би, щоб код перебував у ньому, це законне місце.

Дякую

Checking if a field was changed: Django: When saving, how can you check if a field has changed?

2
Варіант 1 призведе до пари надмірної поведінки моделі - надсилання електронного листа є побічним продуктом подібного випадку, але це не те поведінка, якою модель потребує знань. Ви можете використовувати Джанго-сигнали , щоб створити події і налаштувати оповіщення для приймачів така поведінка.
додано Автор wkl, джерело

2 Відповіді

Ви можете скористатися змінами-моделями django , щоб зробити це без додаткового пошуку в базі даних:

from django.db import models
from django.dispatch import receiver
from django_model_changes import ChangesMixin

class MyModel(ChangesMixin, models.Model):
   # your model

@receiver(pre_save, sender=MyModel)
def send_email_if_changed(sender, instance, **kwargs):
    if 'email' in instance.changes():
        # send email
2
додано

Я б не слідував пораді з посиланням на це питання. Це отримало 18 upvotes але це би з'явилося upvotes не все;). Насправді, це, напевно, просто датовано інформацією (2009 рік).

Набагато краще використовувати сигнал pre_save для цього, що вимагає абсолютно нульових змін у вашій моделі, і тому не має негативних наслідків, таких як відповідь, на яку посилається .

По суті, у вашому методі приймача ви шукаєте об'єкт екземпляра з бази даних. Оскільки це попередньо зберегти, база даних ще не була змінена. В результаті ви можете порівняти instance.some_field з obj.some_field і перевірити, чи вони різні.

@receiver(pre_save, sender=MyModel)
def send_email_if_changed(sender, instance, **kwargs):
    try:
        obj = MyModel.objects.get(pk=instance.pk)
    except MyModel.DoesNotExist:
        pass # It's new, so email hasn't technically changed, but you might want to do something else here.
    else:
        if not obj.email == instance.email: # Email has changed
            # send email
1
додано
Ні, я не думаю, що це можливо. Сигнали не передають нічого назад. Вони просто роблять те, що базуються на цінностях, які їм дано. Але ситуація, яку ви описуєте, все ж таки придумана. Змінити своє запитання на інформацію про те, що ви насправді намагаєтесь виконати.
додано Автор Chris Pratt, джерело
Привіт Кріс, я виконував це і мав невелику проблему. Чи можна відправити електронний лист на нову електронну адресу, але не оновлювати поле адреси електронної пошти в БД, тобто я хочу зберегти стару адресу електронної пошти в БД. (Я знаю, що багато людей не люблять людей, які задають питання в коментарях, але я відчував, що це було безпосередньо пов'язано з тим, що я намагався виконати, і тому я повинен запитати тут.) Спасибі Кріс.
додано Автор Mridang Agarwalla, джерело
@MridangAgarwalla Ви можете пристосувати мою відповідь, щоб зробити те, що хочеш: перезаписати save і зателефонувати собі.changes (), щоб побачити, чи змінено електронний лист, якщо ви могли пропустити виклик super (MyModel, self) .save()
додано Автор Robert Kajic, джерело
ІТ КПІ - Python
ІТ КПІ - Python
625 учасників

Канал обговорень про всякі штуки зі світу пайтону. Прохання: 0. мати повагу одне до одного; 1. не матюкатися в сторону людей; 2. не захламляти тред повідомленнями по одному слову;