Проверка электронной почты в Django

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

Подхожу к проблеме:

  1. Пока пользователь предоставляет электронную почту, он должен проверить, присутствует ли электронная почта в БД. (БД будет обновляться электронными письмами пользователей)
  2. После проверки наличия электронной почты в базе данных пользователю предлагается создать пароль.
  3. После создания пароля пользователь может войти на соответствующую страницу.

Есть ли решение? Я попробовал и последовал:

https://medium.com/@frfahim/django-registration-with-confirmation-email-bb5da011e4ef

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

Есть ли какой-либо сторонний модуль для Django или какое-либо решение для требований, которые я упомянул?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
10
0
28 625
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

У меня есть ответ на вашу первую проблему:

Если вы сбрасываете пароль пользователя на основе PasswordResetView + PasswordResetConfirmView, вы можете сделать следующее:

PasswordResetView отвечает за отправку электронных писем пользователям. Он использует собственную форму для ввода электронных писем пользователей -PasswordResetForm. Вы можете создать свою собственную форму и наследовать ее от PasswordResetForm. Например:


class PRForm(PasswordResetForm):
    def clean_email(self):
        email = self.cleaned_data['email']
        if not User.objects.filter(email__iexact=email, is_active=True).exists():
            msg = "There is no user with this email."
            self.add_error('email', msg)
        return email

# User – your user model or any custom model if you have one instead of the default one

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

Затем укажите эту форму в своем VIEW:


class PassResView(RatelimitMixin,  PasswordResetView):
    success_url = 
    from_email = 
    subject_template_name =
    email_template_name =
    success_message = 
    template_name = 
    form_class = PRForm  # here is a custom form
    ratelimit_key = 'ip'
    ratelimit_rate = '10/5m'
    ratelimit_block = True
    ratelimit_method = ('GET', 'POST')

RatelimitMixin не позволит кому-либо взломать вашу БД путем запуска вашего BD. Вы можете использовать его или нет - решать вам.

рассмотрите мой адрес электронной почты, существующий в классе модели Test (models.Model): first_name = models.CharField (max_length = 200) email_address = models.CharField (max_length = 200), я хочу проверить этот адрес электронной почты и отправить электронное письмо

Joel Deleep 08.04.2019 19:50

если не Test.objects.filter(email_address__iexact=email, is_active=True).exists():

Aleksei Khatkevich 08.04.2019 19:57

еще одно сомнение, код, который вы упомянули, где я должен использовать его в представлениях или в формах??

Joel Deleep 08.04.2019 20:05

Вам лучше прочитать документы Django о PasswordResetView и начать оттуда.

Aleksei Khatkevich 08.04.2019 20:23
Ответ принят как подходящий

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

Модели

class Yourmodel(models.Model):
    first_name = models.CharField(max_length=200)
    second_name = models.CharField(max_length=200)
    email = models.EmailField(max_length=100)

Токены

from django.contrib.auth.tokens import PasswordResetTokenGenerator
from django.utils import six
class TokenGenerator(PasswordResetTokenGenerator):
    def _make_hash_value(self, user, timestamp):
        return (
            six.text_type(user.pk) + six.text_type(timestamp) +
            six.text_type(user.is_active)
        )
account_activation_token = TokenGenerator()

Просмотры

from django.contrib.auth import get_user_model
from django.utils.http import urlsafe_base64_encode, urlsafe_base64_decode
from django.contrib.sites.shortcuts import get_current_site
from .tokens import account_activation_token
from django.core.mail import send_mail

def signup(request):
    User = get_user_model()
    if request.method == 'POST':
        form = SignupForm(request.POST)
        if form.is_valid():
            email = form.cleaned_data.get('email')
            if Yourmodel.objects.filter(email__iexact=email).count() == 1:
                user = form.save(commit=False)
                user.is_active = False
                user.save()
                current_site = get_current_site(request)
                mail_subject = 'Activate your account.'
                message = render_to_string('email_template.html', {
                            'user': user,
                            'domain': current_site.domain,
                            'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                            'token': account_activation_token.make_token(user),
                        })
                to_email = form.cleaned_data.get('email')
                send_mail(mail_subject, message, 'youremail', [to_email])
                return HttpResponse('Please confirm your email address to complete the registration')
     else:
        form = SignupForm()
    return render(request, 'regform.html', {'form': form})

def activate(request, uidb64, token):
    User = get_user_model()
    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 account_activation_token.check_token(user, token):
        user.is_active = True
        user.save()
        return HttpResponse('Thank you for your email confirmation. Now you can login your account.')
    else:
        return HttpResponse('Activation link is invalid!')

Формы

from django.contrib.auth.forms import UserCreationForm


class SignupForm(UserCreationForm):
    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')

Шаблон электронной почты

{% autoescape off %}
Hi ,
Please click on the link to confirm your registration,
http://{{ domain }}{% url 'activate' uidb64=uid token=token %}
{% endautoescape %}

regform.html

{% csrf_token %}
{% for field in form %}
<label >{{ field.label_tag }}</label>
{{ field }}
{% endfor %}

If you don't want to compare with email address in your model you can skip, this will send the email to the email address which was supplied at the time registration without further validation.

email = form.cleaned_data.get('email')
if Yourmodel.objects.filter(email__iexact=email).count() == 1:

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

Addison Klinke 27.05.2021 07:19

откуда вы получаете force_byte, и я не могу импортировать шесть из django utils

nassim 05.06.2021 13:52

@nassim stackoverflow.com/questions/59193514/…

Joel Deleep 05.06.2021 14:21

@nassim Кстати, force_bytes скорее всего происходит от from django.utils.encoding import force_bytes.

Nat Riddle 25.11.2021 19:35

добавьте from django.template.loader import render_to_string сверху

Shayan 22.02.2022 02:02

Для первого ответа нужно добавить urls.py

path('emailVerification/<uidb64>/<token>', views.activate, name='emailActivate')

А emailVerification.html должен быть таким:

    Hi ,
Please click on the link to confirm your registration,
http://{{ domain }}/emailVerification/{{ uid }}/{{ token }}

Другие вопросы по теме