diff --git a/templates/login.html b/templates/login.html
index 69d0540..8d6039d 100644
--- a/templates/login.html
+++ b/templates/login.html
@@ -58,7 +58,7 @@
{% if not form_errors %} {{ msg }} {% endif %}
{% csrf_token %}
--
Gitee
From 5def4d4259c489be464c98bba4a735fc968a2ac3 Mon Sep 17 00:00:00 2001
From: FrodoQian <1296541164@qq.com>
Date: Sun, 5 May 2019 16:00:09 +0800
Subject: [PATCH 6/7] =?UTF-8?q?=E4=B8=80=E4=BA=9B=E4=BF=AE=E6=94=B9?=
=?UTF-8?q?=E8=BF=87=E7=9A=84=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/users/urls.py | 7 +-
apps/users/views.py | 288 ++++++++++++++++++++++++++++++--------
apps/utils/email_send.py | 57 ++++++++
apps/utils/mixin_utils.py | 1 +
boxuegu/settings.py | 12 ++
templates/login.html | 6 +-
templates/register.html | 6 +-
7 files changed, 311 insertions(+), 66 deletions(-)
create mode 100644 apps/utils/email_send.py
diff --git a/apps/users/urls.py b/apps/users/urls.py
index 5ca1b47..8f48b3d 100644
--- a/apps/users/urls.py
+++ b/apps/users/urls.py
@@ -3,8 +3,9 @@ from . import views
urlpatterns = [
# url(r'^register/$',views.UserRegister.as_view()),
- url(r'^register/$', views.UserRegister.as_view(), name='register'),
+ # url(r'^register/$', views.UserRegister.as_view(), name='register'),
+ url(r'^register/$', views.RegisterView.as_view(), name='register'),
url(r'^login/$', views.LoginView.as_view(), name='login'),
-
-
+ url(r'^forget/$', views.ForgetPwdView.as_view(), name='forget_pwd'),
+ url(r'^$', views.IndexView.as_view(), name="index"),
]
diff --git a/apps/users/views.py b/apps/users/views.py
index 9d5635e..155d3f2 100644
--- a/apps/users/views.py
+++ b/apps/users/views.py
@@ -1,95 +1,269 @@
+from django.contrib.auth import authenticate, login
+from django.contrib.auth.backends import ModelBackend
+from django.contrib.auth.hashers import make_password
from django.shortcuts import render
from django.urls import reverse
from django.views import View
-from users.models import UserProfile
-from .forms import RegisterForm, LoginForm
-from django.http import HttpResponse, HttpResponsePermanentRedirect
+from users.models import UserProfile, EmailVerifyRecord
+from .forms import RegisterForm, LoginForm, ForgetForm
+from django.http import HttpResponse, HttpResponsePermanentRedirect, HttpResponseRedirect
+from utils.email_send import send_register_eamil
# Create your views here.
-class UserRegister(View):
+# class UserRegister(View):
+#
+# def get(self, request):
+# """
+# 获取注册页面
+# :param request:
+# :return:
+# """
+# # 生成表单对象
+# register_form = RegisterForm()
+# # 调用模版渲染生成表单
+# return render(request, 'register.html', {'register_form': register_form})
+#
+# def post(self, request):
+# """
+# 验证表单数据
+# :param request:
+# :return:
+# """
+# # 1、获取前端传递的表单数据
+# data = request.POST
+# # 2、验证表单数据
+# register_form = RegisterForm(data)
+#
+# res = register_form.is_valid() # 验证成功返回True,验证失败返回False
+#
+# if res:
+# # 验证成功,则执行相应业务逻辑操作,这里就直接返回验证成功后的字段数据
+# # 获取验证成功后的字段
+# # username = register_form.cleaned_data['username']
+#
+# #
+# # return HttpResponse(username)
+# email = register_form.cleaned_data.get('email')
+# password = register_form.cleaned_data.get('password')
+# user = UserProfile.objects.create(email=email, password=password)
+# return render(request, 'index.html')
+# # email = request.POST.get('email')
+# # password = request.POST.get('password')
+# #
+# #
+# # # 用户处理
+# # user = UserProfile.objects.create_user(
+# # email=email,
+# # password=password,
+# #
+# # )
+#
+# # 验证失败,则在注册模板中通过register_form.errors获取错误
+# return render(request, 'register.html', {'register_form': register_form})
+
+
+# class LoginView(View):
+# def get(self, request):
+# """
+# 获取注册页面
+# :param request:
+# :return:
+# """
+# # 生成表单对象
+# login_form = LoginForm()
+# # 调用模版渲染生成表单
+# return render(request, 'login.html', {'login.html': login_form})
+#
+# def post(self, request):
+# """
+# 验证表单数据
+# :param request:
+# :return:
+# """
+# # 1、获取前端传递的表单数据
+# data = request.POST
+# # 2、验证表单数据
+# login_form = LoginForm(data)
+# res = login_form.is_valid() # 验证成功返回True,验证失败返回False
+#
+# if res:
+# # 验证成功,则执行相应业务逻辑操作,这里就直接返回验证成功后的字段数据
+# # 获取验证成功后的字段
+# username = login_form.cleaned_data['username']
+# pass_word = login_form.cleaned_data['pass_word']
+#
+# # user_name = request.POST.get('username', None)
+# # pass_word = request.POST.get('password', None)
+#
+# return HttpResponsePermanentRedirect(reverse('index'))
+#
+# # 验证失败,则在注册模板中通过register_form.errors获取错误
+# return render(request, 'login.html', {'form_errors': login_form.errors})
+
+
+# users/views.py
+
+# 邮箱和用户名都可以登录
+# 基础ModelBackend类,因为它有authenticate方法
+class CustomBackend(ModelBackend):
+ def authenticate(self, request, username=None, password=None, **kwargs):
+ try:
+ # 不希望用户存在两个,get只能有一个。两个是get失败的一种原因 Q为使用并集查询
+ user = UserProfile.objects.get(Q(username=username) | Q(email=username))
+
+ # django的后台中密码加密:所以不能password==password
+ # UserProfile继承的AbstractUser中有def check_password(self, raw_password):
+ if user.check_password(password):
+ return user
+ except Exception as e:
+ return None
+
+
+class LoginView(View):
+ '''用户登录'''
def get(self, request):
- """
- 获取注册页面
- :param request:
- :return:
- """
- # 生成表单对象
- register_form = RegisterForm()
- # 调用模版渲染生成表单
- return render(request, 'register.html', {'register_form': register_form})
+ return render(request, 'login.html')
def post(self, request):
- """
- 验证表单数据
- :param request:
- :return:
- """
- # 1、获取前端传递的表单数据
- data = request.POST
- # 2、验证表单数据
- register_form = RegisterForm(data)
+ # 实例化
+ login_form = LoginForm(request.POST)
+ if login_form.is_valid():
+ # 获取用户提交的用户名和密码
+ user_name = request.POST.get('username', None)
+ pass_word = request.POST.get('password', None)
+ # 成功返回user对象,失败None
+ user = authenticate(username=user_name, password=pass_word)
+ # 如果不是null说明验证成功
+ if user is not None:
+ if user.is_active:
+ # 只有注册激活才能登录
+ login(request, user)
+ return render(request, 'index.html')
+ else:
+ return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})
+ # 只有当用户名或密码不存在时,才返回错误信息到前端
+ else:
+ return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})
- res = register_form.is_valid() # 验证成功返回True,验证失败返回False
+ # form.is_valid()已经判断不合法了,所以这里不需要再返回错误信息到前端了
+ else:
+ return render(request, 'login.html', {'login_form': login_form})
- if res:
- # 验证成功,则执行相应业务逻辑操作,这里就直接返回验证成功后的字段数据
- # 获取验证成功后的字段
- # username = register_form.cleaned_data['username']
-
- #
- # return HttpResponse(username)
- email = register_form.cleaned_data.get('email')
- password = register_form.cleaned_data.get('password')
- user = UserProfile.objects.create(email=email, password=password)
- return render(request, 'index.html')
- # email = request.POST.get('email')
- # password = request.POST.get('password')
- #
- #
- # # 用户处理
- # user = UserProfile.objects.create_user(
- # email=email,
- # password=password,
- #
- # )
-
- # 验证失败,则在注册模板中通过register_form.errors获取错误
+
+# 激活用户
+class ActiveUserView(View):
+ def get(self, request, active_code):
+ # 查询邮箱验证记录是否存在
+ all_record = EmailVerifyRecord.objects.filter(code=active_code)
+
+ if all_record:
+ for record in all_record:
+ # 获取到对应的邮箱
+ email = record.email
+ # 查找到邮箱对应的user
+ user = UserProfile.objects.get(email=email)
+ user.is_active = True
+ user.save()
+ # 验证码不对的时候跳转到激活失败页面
+ else:
+ return render(request, 'active_fail.html')
+ # 激活成功跳转到登录页面
+ return render(request, "login.html", )
+
+
+class RegisterView(View):
+ '''用户注册'''
+
+ def get(self, request):
+ register_form = RegisterForm()
return render(request, 'register.html', {'register_form': register_form})
+ def post(self, request):
+ register_form = RegisterForm(request.POST)
+ if register_form.is_valid():
+ user_name = request.POST.get('email', None)
+ # 如果用户已存在,则提示错误信息
+ if UserProfile.objects.filter(email=user_name):
+ return render(request, 'register.html', {'register_form': register_form, 'msg': '用户已存在'})
-class LoginView(View):
+ pass_word = request.POST.get('password', None)
+ # 实例化一个user_profile对象
+ user_profile = UserProfile()
+ user_profile.username = user_name
+ user_profile.email = user_name
+ user_profile.is_active = False
+ # 对保存到数据库的密码加密
+ user_profile.password = make_password(pass_word)
+ user_profile.save()
+ send_register_eamil(user_name, 'register')
+ return render(request, 'login.html')
+ else:
+ return render(request, 'register.html', {'register_form': register_form})
+
+
+class ForgetPwdView(View):
def get(self, request):
"""
- 获取注册页面
+ 获取忘记密码页面
:param request:
:return:
"""
# 生成表单对象
- login_form = LoginForm()
+ forget_form = ForgetForm()
# 调用模版渲染生成表单
- return render(request, 'login.html', {'login.html': login_form})
+ return render(request, 'forgetpwd.html', {'forgetpwd.html': forget_form})
def post(self, request):
"""
- 验证表单数据
+ 验证邮箱数据
:param request:
:return:
"""
# 1、获取前端传递的表单数据
data = request.POST
# 2、验证表单数据
- login_form = LoginForm(data)
- res = login_form.is_valid() # 验证成功返回True,验证失败返回False
+ forget_form = ForgetForm(data)
+ res = forget_form.is_valid() # 验证成功返回True,验证失败返回False
if res:
# 验证成功,则执行相应业务逻辑操作,这里就直接返回验证成功后的字段数据
# 获取验证成功后的字段
- username = login_form.cleaned_data['username']
- return HttpResponsePermanentRedirect(reverse('index'))
+ return render(request, 'send_success.html')
+
+ # 验证失败,则在注册模板中通过forget_form.errors获取错误
+ return render(request, 'forgetpwd.html', {'forget_form': forget_form})
+
+
+class IndexView(View):
+
+ def get(self, request):
+ """
+ 获取首页
+ :param request:
+ :return:
+ """
+ # 生成表单对象
- # 验证失败,则在注册模板中通过register_form.errors获取错误
- return render(request, 'login.html', {'form_errors': login_form.errors})
+ # 轮播图
+ all_banners = Banner.objects.all().order_by('index')
+ # 课程
+ courses = Course.objects.filter(is_banner=False)[:6]
+ # 轮播课程
+ banner_courses = Course.objects.filter(is_banner=True)[:3]
+ # 课程机构
+ course_orgs = Course.objects.all()[:15]
+ # 调用模版渲染生成表单
+ return render(request, 'index.html', {
+ 'all_banners': all_banners,
+ 'courses': courses,
+ 'banner_courses': banner_courses,
+ 'course_orgs': course_orgs,
+ })
+ # all_banners 获取轮播图表(Banner)所有轮播图数据
+ # courses 获取课程信息表(Course)中的课程信息数据
+ # banner_courses 获取课程信息表中(Course)的课程信息数据 和上面数据一样
+ # course_orgs 获取课程学校表(CourseOrg)中的数据
diff --git a/apps/utils/email_send.py b/apps/utils/email_send.py
new file mode 100644
index 0000000..5133d6e
--- /dev/null
+++ b/apps/utils/email_send.py
@@ -0,0 +1,57 @@
+# apps/utils/email_send.py
+
+from random import Random
+from django.core.mail import send_mail
+
+from users.models import EmailVerifyRecord
+from boxuegu.settings import EMAIL_FROM
+
+
+# 生成随机字符串
+def random_str(random_length=8):
+ str = ''
+ # 生成字符串的可选字符串
+ chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
+ length = len(chars) - 1
+ random = Random()
+ for i in range(random_length):
+ str += chars[random.randint(0, length)]
+ return str
+
+
+# 发送注册邮件
+def send_register_eamil(email, send_type="register"):
+ # 发送之前先保存到数据库,到时候查询链接是否存在
+ # 实例化一个EmailVerifyRecord对象
+ email_record = EmailVerifyRecord()
+ # 生成随机的code放入链接
+ code = random_str(16)
+ email_record.code = code
+ email_record.email = email
+ email_record.send_type = send_type
+
+ email_record.save()
+
+ # 定义邮件内容:
+ email_title = ""
+ email_body = ""
+
+ if send_type == "register":
+ email_title = "NBA注册激活链接"
+ email_body = "请点击下面的链接激活你的账号: http://127.0.0.1:8000/active/{0}".format(code)
+
+ # 使用Django内置函数完成邮件发送。四个参数:主题,邮件内容,从哪里发,接受者list
+ send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
+ # 如果发送成功
+ if send_status:
+ pass
+
+ if send_type == "forget":
+ email_title = "NBA找回密码链接"
+ email_body = "请点击下面的链接找回你的密码: http://127.0.0.1:8000/reset/{0}".format(code)
+
+ # 使用Django内置函数完成邮件发送。四个参数:主题,邮件内容,从哪里发,接受者list
+ send_status = send_mail(email_title, email_body, EMAIL_FROM, [email])
+ # 如果发送成功
+ if send_status:
+ pass
diff --git a/apps/utils/mixin_utils.py b/apps/utils/mixin_utils.py
index d6c1b67..4650dde 100644
--- a/apps/utils/mixin_utils.py
+++ b/apps/utils/mixin_utils.py
@@ -6,3 +6,4 @@ class LoginRequiredMixin(object):
@method_decorator(login_required(login_url='/login/'))
def dispatch(self, request, *args, **kwargs):
return super(LoginRequiredMixin, self).dispatch(request, *args, **kwargs)
+
diff --git a/boxuegu/settings.py b/boxuegu/settings.py
index 76b811c..9a89e08 100644
--- a/boxuegu/settings.py
+++ b/boxuegu/settings.py
@@ -135,3 +135,15 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'static/media')
# UserProfile 覆盖了 django 内置的 user 表
AUTH_USER_MODEL = 'users.UserProfile'
+
+AUTHENTICATION_BACKENDS = (
+ 'users.views.CustomBackend',
+)
+
+
+EMAIL_HOST = "smtp.qq.com" # SMTP服务器主机
+EMAIL_PORT = 25 # 端口
+EMAIL_HOST_USER = "1296541164@qq.com" # 邮箱地址
+EMAIL_HOST_PASSWORD = "yopkncpjudsjgeaj" # 密码
+EMAIL_USE_TLS= True
+EMAIL_FROM = "1296541164@qq.com" # 邮箱地址
\ No newline at end of file
diff --git a/templates/login.html b/templates/login.html
index 69d0540..7acdab9 100644
--- a/templates/login.html
+++ b/templates/login.html
@@ -27,9 +27,9 @@
@@ -58,7 +58,7 @@
{% if not form_errors %} {{ msg }} {% endif %}
{% csrf_token %}
diff --git a/templates/register.html b/templates/register.html
index 77c5534..5c746d1 100644
--- a/templates/register.html
+++ b/templates/register.html
@@ -27,9 +27,9 @@
@@ -75,7 +75,7 @@
{% csrf_token %}
-{#
已有账号?[立即登录]
#}
+
已有账号?[立即登录]
--
Gitee
From 542f3926006a9f504665655c767fa65e8a43c089 Mon Sep 17 00:00:00 2001
From: FrodoQian <1296541164@qq.com>
Date: Sun, 5 May 2019 17:13:43 +0800
Subject: [PATCH 7/7] =?UTF-8?q?=E5=8F=AF=E4=BB=A5=E5=AE=9E=E7=8E=B0?=
=?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=AF=86=E7=A0=81=E7=9A=84=E9=82=AE=E4=BB=B6?=
=?UTF-8?q?=E6=8E=A5=E6=94=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
apps/users/views.py | 135 ++++----------------------------------------
1 file changed, 10 insertions(+), 125 deletions(-)
diff --git a/apps/users/views.py b/apps/users/views.py
index b59f53a..e2f2ab8 100644
--- a/apps/users/views.py
+++ b/apps/users/views.py
@@ -13,102 +13,6 @@ from .forms import RegisterForm, LoginForm, ForgetForm, ModifyPwdForm
from django.http import HttpResponse, HttpResponsePermanentRedirect
-# Create your views here.
-# class UserRegister(View):
-#
-# def get(self, request):
-# """
-# 获取注册页面
-# :param request:
-# :return:
-# """
-# # 生成表单对象
-# register_form = RegisterForm()
-# # 调用模版渲染生成表单
-# return render(request, 'register.html', {'register_form': register_form})
-#
-# def post(self, request):
-# """
-# 验证表单数据
-# :param request:
-# :return:
-# """
-# # 1、获取前端传递的表单数据
-# data = request.POST
-# # 2、验证表单数据
-# register_form = RegisterForm(data)
-#
-# res = register_form.is_valid() # 验证成功返回True,验证失败返回False
-#
-# if res:
-# # 验证成功,则执行相应业务逻辑操作,这里就直接返回验证成功后的字段数据
-# # 获取验证成功后的字段
-# # username = register_form.cleaned_data['username']
-#
-# #
-# # return HttpResponse(username)
-# email = register_form.cleaned_data.get('email')
-# password = register_form.cleaned_data.get('password')
-# user = UserProfile.objects.create(email=email, password=password)
-# return render(request, 'index.html')
-# # email = request.POST.get('email')
-# # password = request.POST.get('password')
-# #
-# #
-# # # 用户处理
-# # user = UserProfile.objects.create_user(
-# # email=email,
-# # password=password,
-# #
-# # )
-#
-# # 验证失败,则在注册模板中通过register_form.errors获取错误
-# return render(request, 'register.html', {'register_form': register_form})
-
-
-# class LoginView(View):
-# def get(self, request):
-# """
-# 获取注册页面
-# :param request:
-# :return:
-# """
-# # 生成表单对象
-# login_form = LoginForm()
-# # 调用模版渲染生成表单
-# return render(request, 'login.html', {'login.html': login_form})
-#
-# def post(self, request):
-# """
-# 验证表单数据
-# :param request:
-# :return:
-# """
-# # 1、获取前端传递的表单数据
-# data = request.POST
-# # 2、验证表单数据
-# login_form = LoginForm(data)
-# res = login_form.is_valid() # 验证成功返回True,验证失败返回False
-#
-# if res:
-# # 验证成功,则执行相应业务逻辑操作,这里就直接返回验证成功后的字段数据
-# # 获取验证成功后的字段
-# username = login_form.cleaned_data['username']
-# pass_word = login_form.cleaned_data['pass_word']
-#
-# # user_name = request.POST.get('username', None)
-# # pass_word = request.POST.get('password', None)
-#
-# return HttpResponsePermanentRedirect(reverse('index'))
-#
-# # 验证失败,则在注册模板中通过register_form.errors获取错误
-# return render(request, 'login.html', {'form_errors': login_form.errors})
-
-
-# users/views.py
-
-# 邮箱和用户名都可以登录
-# 基础ModelBackend类,因为它有authenticate方法
class CustomBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
try:
@@ -207,38 +111,19 @@ class RegisterView(View):
class ForgetPwdView(View):
- def get(self, request):
- """
- 获取忘记密码页面
- :param request:
- :return:
- """
- # 生成表单对象
+ '''找回密码'''
+ def get(self,request):
forget_form = ForgetForm()
- # 调用模版渲染生成表单
- return render(request, 'forgetpwd.html', {'forgetpwd.html': forget_form})
-
- def post(self, request):
- """
- 验证邮箱数据
- :param request:
- :return:
- """
- # 1、获取前端传递的表单数据
- data = request.POST
- # 2、验证表单数据
- forget_form = ForgetForm(data)
- res = forget_form.is_valid() # 验证成功返回True,验证失败返回False
-
- if res:
- # 验证成功,则执行相应业务逻辑操作,这里就直接返回验证成功后的字段数据
- # 获取验证成功后的字段
+ return render(request,'forgetpwd.html',{'forget_form':forget_form})
+ def post(self,request):
+ forget_form = ForgetForm(request.POST)
+ if forget_form.is_valid():
+ email = request.POST.get('email',None)
+ send_register_eamil(email,'forget')
return render(request, 'send_success.html')
-
- # 验证失败,则在注册模板中通过forget_form.errors获取错误
- return render(request, 'forgetpwd.html', {'forget_form': forget_form})
-
+ else:
+ return render(request,'forgetpwd.html',{'forget_form':forget_form})
class ResetView(View):
def get(self, request, active_code):
--
Gitee