1. 程式人生 > 實用技巧 >django傳送註冊啟用郵件

django傳送註冊啟用郵件

django傳送註冊啟用郵件

使用到的模組詳情

# 1、django內建的郵件功能
from django.core.mail import send_mail   # 傳送郵件
# 2、itsdangerous模組用來進行加密解密
# 使用者註冊完畢後將is_active是否啟用狀態改為未啟用
from itsdangerous import TimedJSONWebSignatureSerializer as TJS

settings.py中配置django內建郵件功能傳送郵件

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend
' EMAIL_HOST = 'smtp.163.com' EMAIL_PORT = 25 EMAIL_HOST_USER = '[email protected]' # 發件人郵箱 EMAIL_HOST_PASSWORD = 'xxxxxxxxxx' # 授權碼 EMAIL_USER_TLS = True # 設定是否啟用了安全連結

lib/send_email/send_email.py

# 傳送郵件功能封裝
from django.core.mail import EmailMultiAlternatives
from django.conf import settings


def send_mail(subject, text_content, img_url, active_link, html_content, recv_email): mail = EmailMultiAlternatives(subject, text_content, from_email=settings.EMAIL_HOST_USER, to=[recv_email, ]) mail.attach_alternative(html_content % {'img_url': img_url, 'link': active_link}, 'text/html') mail.send()

lib/send_email/init.py

from .send_email import send_mail

檢視中編寫郵箱註冊函式(verify_email是使用者點選郵箱中連結訪問的啟用檢視)

from rest_framework.viewsets import GenericViewSet
from alias.utils.response import APIResponse
from itsdangerous import TimedJSONWebSignatureSerializer as TJS   # 對郵件中的url包含的啟用資訊進行加密
from rest_framework.decorators import action  # 裝飾器
from django.conf import settings
from . import models
from . import serializers

class EmailRegisterView(GenericViewSet):
    """
    # 郵箱註冊介面
    路由:http://127.0.0.1:8000/user/email_register/
    """

    queryset = models.User.objects.all()
    serializer_class = serializers.EmailRegisterModelSerializer

    @staticmethod
    def send_email(recv_email):
        from alias.lib.send_email import send_mail
        Ts = TJS(settings.SECRET_KEY, expires_in=600)
        token = Ts.dumps(recv_email)
        text_content = '註冊啟用郵件'
        active_link = settings.BASE_URL + '/user/verify_email/?token=' + token.decode()
        print(active_link)
        img_url = settings.IMG_URL
        html_content = """
            <div style="background-image: url(%(img_url)s); background-repeat: no-repeat">
                <p>尊敬的使用者:</p><br>
                <p>&nbsp;&nbsp;&nbsp;&nbsp;您好,歡迎註冊白菜小技術,請點選<a href="%(link)s" style="text-decoration: none">啟用連結</a>完成啟用,有效時間10分鐘。</p><br>
                <p>&nbsp;&nbsp;&nbsp;&nbsp;如果您無法開啟該連結,請複製%(link)s 到瀏覽器中完成啟用。</p><br>
                <p>&nbsp;&nbsp;&nbsp;&nbsp;再次感謝您的註冊。</p>
            </div>
            """
        send_mail('白菜小技術註冊郵件', text_content, img_url, active_link, html_content, recv_email)

    @action(methods=['POST', ], detail=False)
    def email_register(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data, context={})
        serializer.is_valid(raise_exception=True)
        serializer.save()
        recv_email = serializer.context.get('username', None)
        self.send_email(recv_email)
        return APIResponse(
            msg='註冊成功,請到郵箱中完成啟用'
        )

    @staticmethod
    def obtain_user(token):
        Ts = TJS(settings.SECRET_KEY)
        user_msg = Ts.loads(token.encode())
        print(user_msg)
        user = models.User.objects.filter(username=user_msg)
        return user

    @action(methods=['GET', ], detail=False)
    def verify_email(self, request, *args, **kwargs):
        token = request.query_params.get('token', None)
        if not token:
            return APIResponse(code=106, msg='啟用失敗', data={'result': '缺少認證引數token'})
        user = self.obtain_user(token)
        if not user:
            return APIResponse(code=107, msg='啟用失敗', data={'result': '使用者不存在'})
        user.update(is_active=1)
        return APIResponse(msg='啟用成功')

序列化器serializers.py

# 郵箱註冊的序列化器
class EmailRegisterModelSerializer(serializers.ModelSerializer):
    re_password = serializers.CharField(min_length=8, max_length=16, write_only=True)
    email = serializers.CharField(write_only=True)

    class Meta:
        model = models.User
        fields = ['email', 'password', 're_password', 'username']

        extra_kwargs = {
            'password': {'max_length': 16, 'min_length': 8},
            'username': {'read_only': True}
        }

    def _check_email(self, email):
        return bool(models.User.objects.filter(email=email, is_delete=False))

    def _check_password(self, attrs):
        password = attrs.get('password', None)
        re_password = attrs.pop('re_password', None)
        return bool(password == re_password)

    def validate(self, attrs):

        email = attrs.pop('email', None)
        if self._check_email(email):
            raise ValidationError('賬號已存在,請直接登入')
        if not self._check_password(attrs):
            raise ValidationError('兩次密碼輸入不一致')
        attrs['email'] = email
        attrs['username'] = email
        self.context['username'] = email
        return attrs

    def create(self, validated_data):
        instance = models.User.objects.create_user(**validated_data)
        instance.is_active = 0
        instance.save()
        return instance

路由urls.py

from django.urls import path,re_path,include
from . import views
from rest_framework.routers import SimpleRouter


router = SimpleRouter()
router.register('', views.SendSmSView, 'send')
router.register('register', views.RegisterView, 'register')
router.register('', views.EmailRegisterView, 'email_register')  # 郵件註冊和啟用的檢視

urlpatterns = [
    path('', include(router.urls)),
]