Подтверждение по электронной почте не отправляется после регистрации. Джанго + Сельдерей ⇐ Python
-
Anonymous
Подтверждение по электронной почте не отправляется после регистрации. Джанго + Сельдерей
Я использую Windows без WSL. Недавно я установил Redis для кэширования в своем проекте Django. Я сделал это без проблем, используя эту ссылку: https://github.com/microsoftarchive/redis/releases
Следующей задачей была работа с Celery для оптимизации регистрации (если я правильно понимаю, смотрю курс разработки). Я сделал все как в моем курсе. Но проверка электронной почты не сработала.
У меня тот же код, что и у автора. Но автор использует MacOS.
Я не до конца понимаю работу с Celery, но мне нужно это сделать.
Буду благодарен за помощь!
база — корневой каталог
пользователи - приложение для работы с пользователями
base/_init_.py:
из приложения импорта .celery как celery_app __all__ = ('сельдерей_приложение',) base/celery.py:
импортировать ОС из импортного сельдерея Сельдерей os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'base.settings') приложение = Сельдерей('база') app.config_from_object('django.conf:settings', namespace='СЕЛЬДЕРЕЙ') app.autodiscover_tasks() base/settings.py:
CELERY_BROKER_URL: str = 'redis://127.0.0.1:6379' CELERY_RESULT_BACKEND: str = 'redis://127.0.0.1:6379' users/forms.py:
класс UserRegistrationForm(UserCreationForm): first_name = form.CharField(widget=forms.TextInput(attrs={ 'класс': 'form-control py-4', 'placeholder': 'Введите имя', })) Last_name = form.CharField(widget=forms.TextInput(attrs={ 'класс': 'form-control py-4', 'placeholder': 'Введите фамилию', })) имя пользователя = form.CharField(widget=forms.TextInput(attrs={ 'класс': 'form-control py-4', 'placeholder': "Введите имя пользователя", })) электронная почта = form.CharField(widget=forms.EmailInput(attrs={ 'класс': 'form-control py-4', 'placeholder': 'Введите адрес электронной почты', })) пароль1 = form.CharField(widget=forms.PasswordInput(attrs={ 'класс': 'form-control py-4', 'placeholder': 'Введите пароль', })) пароль2 = form.CharField(widget=forms.PasswordInput(attrs={ 'класс': 'form-control py-4', 'placeholder': 'Подтвердите пароль', })) класс Мета: модель = Пользователь поля: list[str] = ['first_name', 'last_name', 'username', 'email', 'password1', 'password2'] def save(self, commit: bool = True): пользователь = super().save(commit=True) send_email_verification.delay(user.id) вернуть пользователя users/models.py:
класс EmailVerification(models.Model): код = модели.UUIDField(уникальный=True) пользователь = модели.ForeignKey(to=Пользователь, on_delete=models.CASCADE) создано = models.DateTimeField(auto_now_add=True) истечение = модели.DateTimeField() def __str__(self) -> str: вернуть f'EmailVerification объект для {self.user.email}' def send_verification_email(self) -> Нет: ссылка: str =verse('users:email_verification', kwargs={'email': self.user.email, 'code': self.code}) verification_link: str = f'{settings.DOMAIN_NAME}{ссылка}' subject: str = f'Подтверждение учетной записи для {self.user.username}' сообщение: str = f'Чтобы подтвердить учетную запись {self.user.email}, перейдите по этой ссылке {verification_link}' Отправить письмо( тема = тема, сообщение = сообщение, from_email=settings.EMAIL_HOST_USER, получатель_список=[self.user.email], неудачно_тихо = Ложь, ) def is_expired(self) -> bool: вернуть True, если сейчас() >= self.expiration, иначе False users/tasks.py:
импортировать uuid из даты и времени импорта timedelta из импорта сельдерея Shared_task из импорта django.utils.timezone сейчас от пользователей.модели импортируют EmailVerification, User @shared_task защита send_email_verification (user_id: int): пользователь = User.objects.get(id=user_id) срок действия = сейчас () + дельта времени (часов = 48) запись = EmailVerification.objects.create(code=uuid.uuid4(), пользователь=пользователь, срок действия=истек) запись.send_verification_email() users/views.py:
класс EmailVerificationView(TitleMixin, TemplateView): title: str = 'SyCloth — проверка электронной почты' имя_шаблона: str = 'users/email_verification.html' def get(self, request, *args: Any, **kwargs: dict[str, Any]): код = kwargs['код'] пользователь = User.objects.get(email=kwargs['email']) email_verifications = EmailVerification.objects.filter(пользователь=пользователь, код=код) если email_verifications.exists(), а не email_verifications.first().is_expired(): user.is_verified_email = Истина пользователь.сохранить() return super(EmailVerificationView, self).get(request, *args, **kwargs) еще: вернуть HttpResponseRedirect(обратный('индекс')) Ответ сельдерея:
сельдерей -A базовый рабочий -l ИНФОРМАЦИЯ -------------- celery@S0fft v5.3.4 (изумрудный пик) --- ***** ----- - *** --- * --- - ** ---------- [конфигурация] - ** ---------- .> приложение: база: 0x26b820534d0 - ** ---------- .> транспорт: redis://127.0.0.1:6379// - ** ---------- .> результаты: redis://127.0.0.1:6379/ - *** --- * --- .> параллелизм: 4 (префорк) -- ******* ---- .> события задачи: ВЫКЛ (включите -E для мониторинга задач в этом работнике) --- ***** ----- -------------- [очереди] .> сельдерей обмен = сельдерей (прямой) ключ = сельдерей [задания] . пользователи.задачи.send_email_verification [2023-11-01 09:45:19,026: WARNING/MainProcess] C:\Development\sycloth\.venv\Lib\site-packages\celery\worker\consumer\consumer.py:507: CPendingDeprecationWarning: параметр конфигурацииbroker_connection_retry больше не буду определять выполняются ли повторные попытки подключения брокера во время запуска в Celery 6.0 и выше. Если вы хотите сохранить существующее поведение при повторных попытках подключения при запуске, вам следует установить дляbroker_connection_retry_on_startup значение True. предупреждения.предупреждать( [2023-11-01 09:45:19,026: INFO/MainProcess] Подключено к redis://127.0.0.1:6379// [2023-11-01 09:45:19,026: WARNING/MainProcess] C:\Development\sycloth\.venv\Lib\site-packages\celery\worker\consumer\consumer.py:507: CPendingDeprecationWarning: параметр конфигурацииbroker_connection_retry больше не буду определять выполняются ли повторные попытки подключения брокера во время запуска в Celery 6.0 и выше. Если вы хотите сохранить существующее поведение при повторных попытках подключения при запуске, вам следует установить дляbroker_connection_retry_on_startup значение True. предупреждения.предупреждать( [2023-11-01 09:45:19,033: INFO/MainProcess] смешиваться: поиск соседей [2023-11-01 09:45:19,456: INFO/SpawnPoolWorker-4] дочерний процесс 2600, вызывающий self.run() [2023-11-01 09:45:19,462: INFO/SpawnPoolWorker-3] дочерний процесс 12996, вызывающий self.run() [2023-11-01 09:45:19,474: INFO/SpawnPoolWorker-2] дочерний процесс 13852, вызывающий self.run() [2023-11-01 09:45:19,481: INFO/SpawnPoolWorker-1] дочерний процесс 4484, вызывающий self.run() [2023-11-01 09:45:20,058: INFO/MainProcess] смешиваться: совсем один [2023-11-01 09:45:20,078: INFO/MainProcess] celery@S0fft готов. [2023-11-01 09:47:26,420: INFO/MainProcess] Задача user.tasks.send_email_verification[38683e5e-b122-45eb-914f-f718fb32f9af] получена [2023-11-01 09:47:27,021: INFO/SpawnPoolWorker-6] дочерний процесс 13688, вызывающий self.run() [2023-11-01 09:47:27,021: INFO/SpawnPoolWorker-5] дочерний процесс 10364, вызывающий self.run() [2023-11-01 09:47:27,102: INFO/SpawnPoolWorker-7] дочерний процесс 7488, вызывающий self.run() Редис:
redis-cli.exe 127.0.0.1:6379> пинг ПОНГ 127.0.0.1:6379> с
Я использую Windows без WSL. Недавно я установил Redis для кэширования в своем проекте Django. Я сделал это без проблем, используя эту ссылку: https://github.com/microsoftarchive/redis/releases
Следующей задачей была работа с Celery для оптимизации регистрации (если я правильно понимаю, смотрю курс разработки). Я сделал все как в моем курсе. Но проверка электронной почты не сработала.
У меня тот же код, что и у автора. Но автор использует MacOS.
Я не до конца понимаю работу с Celery, но мне нужно это сделать.
Буду благодарен за помощь!
база — корневой каталог
пользователи - приложение для работы с пользователями
base/_init_.py:
из приложения импорта .celery как celery_app __all__ = ('сельдерей_приложение',) base/celery.py:
импортировать ОС из импортного сельдерея Сельдерей os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'base.settings') приложение = Сельдерей('база') app.config_from_object('django.conf:settings', namespace='СЕЛЬДЕРЕЙ') app.autodiscover_tasks() base/settings.py:
CELERY_BROKER_URL: str = 'redis://127.0.0.1:6379' CELERY_RESULT_BACKEND: str = 'redis://127.0.0.1:6379' users/forms.py:
класс UserRegistrationForm(UserCreationForm): first_name = form.CharField(widget=forms.TextInput(attrs={ 'класс': 'form-control py-4', 'placeholder': 'Введите имя', })) Last_name = form.CharField(widget=forms.TextInput(attrs={ 'класс': 'form-control py-4', 'placeholder': 'Введите фамилию', })) имя пользователя = form.CharField(widget=forms.TextInput(attrs={ 'класс': 'form-control py-4', 'placeholder': "Введите имя пользователя", })) электронная почта = form.CharField(widget=forms.EmailInput(attrs={ 'класс': 'form-control py-4', 'placeholder': 'Введите адрес электронной почты', })) пароль1 = form.CharField(widget=forms.PasswordInput(attrs={ 'класс': 'form-control py-4', 'placeholder': 'Введите пароль', })) пароль2 = form.CharField(widget=forms.PasswordInput(attrs={ 'класс': 'form-control py-4', 'placeholder': 'Подтвердите пароль', })) класс Мета: модель = Пользователь поля: list[str] = ['first_name', 'last_name', 'username', 'email', 'password1', 'password2'] def save(self, commit: bool = True): пользователь = super().save(commit=True) send_email_verification.delay(user.id) вернуть пользователя users/models.py:
класс EmailVerification(models.Model): код = модели.UUIDField(уникальный=True) пользователь = модели.ForeignKey(to=Пользователь, on_delete=models.CASCADE) создано = models.DateTimeField(auto_now_add=True) истечение = модели.DateTimeField() def __str__(self) -> str: вернуть f'EmailVerification объект для {self.user.email}' def send_verification_email(self) -> Нет: ссылка: str =verse('users:email_verification', kwargs={'email': self.user.email, 'code': self.code}) verification_link: str = f'{settings.DOMAIN_NAME}{ссылка}' subject: str = f'Подтверждение учетной записи для {self.user.username}' сообщение: str = f'Чтобы подтвердить учетную запись {self.user.email}, перейдите по этой ссылке {verification_link}' Отправить письмо( тема = тема, сообщение = сообщение, from_email=settings.EMAIL_HOST_USER, получатель_список=[self.user.email], неудачно_тихо = Ложь, ) def is_expired(self) -> bool: вернуть True, если сейчас() >= self.expiration, иначе False users/tasks.py:
импортировать uuid из даты и времени импорта timedelta из импорта сельдерея Shared_task из импорта django.utils.timezone сейчас от пользователей.модели импортируют EmailVerification, User @shared_task защита send_email_verification (user_id: int): пользователь = User.objects.get(id=user_id) срок действия = сейчас () + дельта времени (часов = 48) запись = EmailVerification.objects.create(code=uuid.uuid4(), пользователь=пользователь, срок действия=истек) запись.send_verification_email() users/views.py:
класс EmailVerificationView(TitleMixin, TemplateView): title: str = 'SyCloth — проверка электронной почты' имя_шаблона: str = 'users/email_verification.html' def get(self, request, *args: Any, **kwargs: dict[str, Any]): код = kwargs['код'] пользователь = User.objects.get(email=kwargs['email']) email_verifications = EmailVerification.objects.filter(пользователь=пользователь, код=код) если email_verifications.exists(), а не email_verifications.first().is_expired(): user.is_verified_email = Истина пользователь.сохранить() return super(EmailVerificationView, self).get(request, *args, **kwargs) еще: вернуть HttpResponseRedirect(обратный('индекс')) Ответ сельдерея:
сельдерей -A базовый рабочий -l ИНФОРМАЦИЯ -------------- celery@S0fft v5.3.4 (изумрудный пик) --- ***** ----- - *** --- * --- - ** ---------- [конфигурация] - ** ---------- .> приложение: база: 0x26b820534d0 - ** ---------- .> транспорт: redis://127.0.0.1:6379// - ** ---------- .> результаты: redis://127.0.0.1:6379/ - *** --- * --- .> параллелизм: 4 (префорк) -- ******* ---- .> события задачи: ВЫКЛ (включите -E для мониторинга задач в этом работнике) --- ***** ----- -------------- [очереди] .> сельдерей обмен = сельдерей (прямой) ключ = сельдерей [задания] . пользователи.задачи.send_email_verification [2023-11-01 09:45:19,026: WARNING/MainProcess] C:\Development\sycloth\.venv\Lib\site-packages\celery\worker\consumer\consumer.py:507: CPendingDeprecationWarning: параметр конфигурацииbroker_connection_retry больше не буду определять выполняются ли повторные попытки подключения брокера во время запуска в Celery 6.0 и выше. Если вы хотите сохранить существующее поведение при повторных попытках подключения при запуске, вам следует установить дляbroker_connection_retry_on_startup значение True. предупреждения.предупреждать( [2023-11-01 09:45:19,026: INFO/MainProcess] Подключено к redis://127.0.0.1:6379// [2023-11-01 09:45:19,026: WARNING/MainProcess] C:\Development\sycloth\.venv\Lib\site-packages\celery\worker\consumer\consumer.py:507: CPendingDeprecationWarning: параметр конфигурацииbroker_connection_retry больше не буду определять выполняются ли повторные попытки подключения брокера во время запуска в Celery 6.0 и выше. Если вы хотите сохранить существующее поведение при повторных попытках подключения при запуске, вам следует установить дляbroker_connection_retry_on_startup значение True. предупреждения.предупреждать( [2023-11-01 09:45:19,033: INFO/MainProcess] смешиваться: поиск соседей [2023-11-01 09:45:19,456: INFO/SpawnPoolWorker-4] дочерний процесс 2600, вызывающий self.run() [2023-11-01 09:45:19,462: INFO/SpawnPoolWorker-3] дочерний процесс 12996, вызывающий self.run() [2023-11-01 09:45:19,474: INFO/SpawnPoolWorker-2] дочерний процесс 13852, вызывающий self.run() [2023-11-01 09:45:19,481: INFO/SpawnPoolWorker-1] дочерний процесс 4484, вызывающий self.run() [2023-11-01 09:45:20,058: INFO/MainProcess] смешиваться: совсем один [2023-11-01 09:45:20,078: INFO/MainProcess] celery@S0fft готов. [2023-11-01 09:47:26,420: INFO/MainProcess] Задача user.tasks.send_email_verification[38683e5e-b122-45eb-914f-f718fb32f9af] получена [2023-11-01 09:47:27,021: INFO/SpawnPoolWorker-6] дочерний процесс 13688, вызывающий self.run() [2023-11-01 09:47:27,021: INFO/SpawnPoolWorker-5] дочерний процесс 10364, вызывающий self.run() [2023-11-01 09:47:27,102: INFO/SpawnPoolWorker-7] дочерний процесс 7488, вызывающий self.run() Редис:
redis-cli.exe 127.0.0.1:6379> пинг ПОНГ 127.0.0.1:6379> с
Мобильная версия