Почему мой код django не отправляет электронное письмо моему новому зарегистрированному пользователю? - PullRequest
0 голосов
/ 09 мая 2020

Я хочу подтвердить регистрацию нового пользователя, отправив токен подтверждения на электронную почту пользователя. код не показывает ошибок в консоли, но также не отправляет электронное письмо на адрес электронной почты пользователя. Я использую django 3.0 и python 3.8.

код выполняет эту часть, когда я регистрирую нового пользователя, это сообщение появляется, но я не получаю электронную почту "Open your email to activate account."

помогите мне исправить это:

views.py

from .forms import CreateUserForm
from django.views import View

from django.utils.encoding import force_bytes, force_text
from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode
from django.contrib.sites.shortcuts import get_current_site
from django.template.loader import render_to_string

from django.core.mail import EmailMessage
from .tokens import activation_token

from django.contrib.auth.models import User

from django.contrib import messages


class RegisterPageView(View):
    def get(self, request, *args, **kwargs):
        form = CreateUserForm()
        template_name = "register/register.html"
        return render(request, template_name, {"form": form})

    def post(self, request, *args, **kwargs):
        form = CreateUserForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.is_active = False
            user.save()
            message_subject = "Activate your account"
            domain_url = get_current_site(request)
            user_email = form.cleaned_data["email"]
            message = render_to_string(
                "Backend/accounts/activation_message.html",
                {
                    "domain": domain_url.domain,
                    "user": user,
                    "uid": urlsafe_base64_encode(force_bytes(user.id)),
                    "token": activation_token.make_token(user),
                },
            )
            email = EmailMessage(message_subject, message, to=[user_email])
            email.send()
            activation_msg = "Open your email to activate account."
            return render(
                request, "Backend/accounts/activate_email.html", {"activation_msg": activation_msg}
            )

        template_name = 'register/register.html'
        return render(request, template_name, {"form": form})

urls.py

from django.urls import path
from .views import *
from django.contrib.auth import views as auth_views

urlpatterns = [
    path('', index, name="index"),
    path("activate/<uidb64>/<token>", activate, name="activate"),
    path("register/", RegisterPageView.as_view(), name="register"),
]

forms.py

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms


class CreateUserForm(UserCreationForm):
    class Meta:
        model = User
        fields = ("username", "email", "password1", "password2","first_name","last_name")

    def clean_email(self):
        data = self.cleaned_data["email"]
        try:
            user_email = User.objects.get(email=data)
        except User.DoesNotExist:
            pass
        else:
            raise forms.ValidationError("Email already exist")

settings .py

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_USE_TLS = True
EMAIL_HOST_USER = 'mymail'
EMAIL_HOST_PASSWORD = 'mypassword'

Ответы [ 3 ]

0 голосов
/ 09 мая 2020

Следующее может быть одной из возможностей:

  • Убедитесь, что SMTP-конфигурация вашей учетной записи Gmail в порядке и разрешает доступ к django: https://support.google.com/accounts/answer/6010255?hl=en
  • Вы можете, если это не проблема smtp, отправив электронное письмо на консоль, изменив EMAIL_BACKEND 'django.core.mail.backends.smtp.EmailBackend' To "django.core.mail.backends.console.EmailBackend"

    Если электронное письмо отображается в консоли, попробуйте настройки адаптеров учетной записи : https://django-allauth.readthedocs.io/en/latest/configuration.html

  • В качестве альтернативы вы можете попробовать этот код, так как он работает у меня:


     subject = 'Thank you for registering to our site'
          message = 'this is a test message'
          email_from = 'xyz@gmail.com'
          recipient_list = ['reciever@gmail.com', ]
          connection = [
              'xyz@gmail.com',
              'mypassword',
              False,
          ]
         send_mail(subject, message, email_from, recipient_list, connection)

для этого вам нужно будет импортировать send_mail: https://docs.djangoproject.com/en/3.0/topics/email/

0 голосов
/ 09 мая 2020

Я обновил какую-то часть, а остальные такие же ..

from django.core.mail import send_mail

class RegisterPageView(View):
        def get(self, request, *args, **kwargs):
            form = CreateUserForm()
            template_name = "register/register.html"
            return render(request, template_name, {"form": form})

        def post(self, request, *args, **kwargs):
            form = CreateUserForm(request.POST)
            if form.is_valid():
                user = form.save(commit=False)
                user.is_active = False
                user.save()
                subject = "Activate your account"
                domain_url = get_current_site(request)
                message = render_to_string(
                    "Backend/accounts/activation_message.html",
                    {
                        "domain": domain_url.domain,
                        "user": user,
                        "uid": urlsafe_base64_encode(force_bytes(user.pk)),
                        "token": activation_token.make_token(user),
                    },
                )
                to_email = form.cleaned_data.get('email')
                send_mail(subject, message, 'mygmail@gmail.com', [to_email])
                activation_msg = "Open your email to activate account."
                return render(
                    request, "Backend/accounts/activate_email.html", {"activation_msg": activation_msg}
                )

            template_name = 'register/register.html'
            return render(request, template_name, {"form": form})

    def activate(request, uidb64, token):
        try:
            uid = force_text(urlsafe_base64_decode(uidb64))
            user = User.objects.get(pk=uid)
        except (TypeError, ValueError, OverflowError, User.DoesNotExist):
            user = None

        if user is not None and activation_token.check_token(user, token):
            user.is_active = True
            user.profile.email_confirmed = True
            user.save()
            login(request, user)
            return redirect('login')
        else:
            return render(request, "Backend/accounts/activation_fail.html")

Я использовал email_confirmed для проверки правильности электронной почты, также я добавил email_confirmed = models.BooleanField(default=False) эту строку в свой профиль пользователя

class Profile(models.Model):
    user=models.OneToOneField(User,on_delete=models.CASCADE,null=True,blank=True)
    phone=models.CharField("Write Phone Name", max_length=100,null=True,blank=True)
    image=models.ImageField("Upload Client Image",null=True,blank=True)
    gender=models.CharField("Write gender", max_length=100,null=True,blank=True)
    position=models.CharField("Designation", max_length=100,null=True,blank=True)
    email_confirmed = models.BooleanField(default=False)

вот и все .. спасибо за помощь

0 голосов
/ 09 мая 2020

Ваш адрес электронной почты в setting.py должен выглядеть следующим образом:

EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_HOST = "smtp.gmail.com"  # mail service smtp
EMAIL_HOST_USER = "youremail@gmail.com"  # mymial is not any email: use environment variable to hide your email in production.
EMAIL_HOST_PASSWORD = "your email password"  # password
EMAIL_PORT = 587
EMAIL_USE_TLS = True

Примечание: вы должны сделать свою учетную запись Gmail менее безопасной.

Go по этой ссылке

И сделайте как на рисунке. enter image description here

В качестве альтернативы вы можете попробовать следующее:

class RegisterPageView(View):
    def get(self, request, *args, **kwargs):
        form = CreateUserForm()
        template_name = "register/register.html"
        return render(request, template_name, {"form": form})

    def post(self, request, *args, **kwargs):
        form = CreateUserForm(request.POST)
        if form.is_valid():
            user = form.save(commit=False)
            user.is_active = False
            user.save()
            message_subject = "Activate your account"
            domain_url = get_current_site(request)
            user_email = form.cleaned_data["email"]
            message = render_to_string(
                "Backend/accounts/activation_message.html",
                {
                    "domain": domain_url.domain,
                    "user": user,
                    "uid": urlsafe_base64_encode(force_bytes(user.id)),
                    "token": activation_token.make_token(user),
                },
            )
            user.email_user(subject, message) #try this
            activation_msg = "Open your email to activate account."
            return render(
                request, "Backend/accounts/activate_email.html", {"activation_msg": activation_msg}
            )

        template_name = 'register/register.html'
        return render(request, template_name, {"form": form})
...