说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢你们!css
接着上一篇博客继续往下写 :http://www.javashuo.com/article/p-hjnmskdq-hs.htmlhtml
目录前端
一丶用户注册python
二丶用户登陆mysql
1.显示用户注册页面redis
# /user/register def register(request): """显示注册页面""" return render(request, "register.html")
urlpatterns = [ url(r"^register$", views.register, name="register") # 注册页 ]
{% load staticfiles %} <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>每天生鲜-注册</title> <link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}"> <link rel="stylesheet" type="text/css" href="{% static 'css/main.css' %}">
2.定义注册页面表单数据视图函数sql
<form method="post" action="/user/register_handle">
<form method="post" action="/user/register_handle"> {% csrf_token %}
# /user/register/handle def register_handle(request): """处理用户注册数据""" pass
url(r"^register_handle$", views.register_handle, name="register_handle") # 注册数据处理
3.视图函数register_handle代码逻辑实现数据库
username = request.POST.get("user_name") password = request.POST.get("pwd") email = request.POST.get("email") allow = request.POST.get("allow")
if not all([username, password, email]): return render(request, "register.html", {"error_msg":"数据不完整"})
if not re.match(r"^[a-z0-9][\w.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$", email): return render(request, "register.html", {"error_msg":"邮箱格式不正确"})
if allow != "on": return render(request, "register.html", {"error_msg":"请勾选赞成"})
user = User.objects.create_user(username, email, password)
return redirect(reverse("goods:index"))
# http://127.0.0.1:8000 def index(request): """显示首页""" return render(request, "index.html")
urlpatterns = [ url(r"^$", views.index, name="index"), # 首页 ]
说明:前端注册页面使用js对密码长度和两次密码是否一致以及邮箱地址是否赞成都进行了校验django
user.is_active = 0 user.save()
try: user = User.objects.get(username=username) except User.DoesNotExist: """若是出现该异常说明用户名不存在,则让user对象为空""" user = None # 若是user对象存在,则表示用户名已存在,返回错误提示信息 if user: return render(request, "register.html", {"error_msg":"用户名已存在"})
4.测试数据不合法的状况下,提示错误信息windows
<span style="color: red">{{ error_msg }}</span>
5.注册优化处理,让显示注册页面和注册数据处理为同一个url地址(/user/register) ,由于显示注册页面为get请求,而注册数据处理为post请求,能够根据请求方式不一样来使用同一个url地址
<form method="post" action="/user/register">
# Create your views here. # /user/register def register(request): """注册""" # 当请求方式为get时表示请求注册页面,反之为处理用户注册数据 if request.method == "GET": """显示注册页面""" return render(request, "register.html") else: """处理用户注册数据"""
6.使用类视图来区分用户请求
from django.views.generic import View # /user/register class RegisterView(View): """注册""" def get(self, request): """显示注册页面""" return render(request, "register.html") def post(self, request): """处理用户注册数据"""
urlpatterns = [ url(r"^register$", RegisterView.as_view(), name="register"), # 注册 ]
7. 生成用户激活邮件中的token,当在不错的网站进行用户注册成功后,会想用户注册填写的邮箱地址发送帐户激活的邮件,在这个邮件内容中会有一个激活的连接地址,而且会提示用户请在2小时内进行激活,2小时后失效;定义激活连接为http://127.0.0.1:8000/user/active/用户id,若是在连接地址明文显示用户的id值的话,就会出现某些懂技术的用户,修改连接地址中的用户id,就颇有可能去激活其余用户,因此须要将连接地址中的用户id值进行加密并设置密钥的有效期
pip install itsdangerous
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
serializer = Serializer(settings.SECRET_KEY, 3600) # 有效期1小时 info = {"confirm":user.id} token = serializer.dumps(info)
8.使用django内置函数发送邮件(这个QQ邮箱为博主小小小小号)
# 发送邮件配置 EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = 'smtp.qq.com' EMAIL_PORT = 25 #发送邮件的邮箱 EMAIL_HOST_USER = '2384005622@qq.com' #在邮箱中设置的客户端受权密码 EMAIL_HOST_PASSWORD = '受权码' #收件人看到的发件人 EMAIL_FROM = '每天生鲜<2384005622@qq.com>'
from django.core.mail import send_mail
subject = "每天生鲜欢迎你" # 邮件标题 message = "how are you" # 邮件正文 sender = settings.EMAIL_FROM # 发件人 receiver = [email] # 收件人 send_mail(subject, message, sender, receiver)
subject = "每天生鲜欢迎你" # 邮件标题 message = '' # 邮件正文 sender = settings.EMAIL_FROM # 发件人 receiver = [email] # 收件人 html_message = """ <h1>%s 恭喜您成为每天生鲜注册会员</h1><br/><h3>请您在1小时内点击如下连接进行帐户激活</h3><a href="http://127.0.0.1:8000/user/active/%s">http://127.0.0.1:8000/user/active/%s</a> """ % (username, token, token) send_mail(subject, message, sender, receiver, html_message=html_message)
9.用户注册激活
# /user/active/...... class ActiveView(View): """帐户激活""" def get(self, request, token): """进行用户激活""" pass
serializer = Serializer(settings.SECRET_KEY, 3600)
try: info = serializer.loads(token) # 获取用户id user_id = info['confirm'] # 根据用户id 获取该用户对象 user = User.objects.get(id=user_id) # 设置该用户对象中的is_active字段的值为1 user.is_active = 1 user.save() # 使用反向解析跳转到登陆页 return redirect(reverse("user:login")) except SignatureExpired as e: # 出现异常表示连接失效 return HttpResponse("激活连接已过时")
# /user/login class LoginView(View): """登陆""" def get(self, request): """显示登陆页""" return render(request, "login.html")
url(r"^active/(?P<token>.*)$", ActiveView.as_view(), name="active"), # 帐户激活 url(r"^login$", LoginView.as_view(), name="login"), # 登陆
10.使用celery异步发送邮件
app = Celery("celery_tasks.tasks", broker="redis://127.0.0.1:6379/4")
@app.task def send_active_email(to_email, username, token): """发送用户激活邮件""" subject = "每天生鲜欢迎你" # 邮件标题 message = '' # 邮件正文 sender = settings.EMAIL_FROM # 发件人 receiver = [to_email] # 收件人 html_message = """ <h1>%s 恭喜您成为每天生鲜注册会员</h1><br/><h3>请您在1小时内点击如下连接进行帐户激活</h3><a href="http://127.0.0.1:8000/user/active/%s">http://127.0.0.1:8000/user/active/%s</a> """ % (username, token, token) send_mail(subject, message, sender, receiver, html_message=html_message) # 为了体现出celery异步完成发送邮件,这里睡眠5秒 time.sleep(5)
import os import django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dailyfresh.settings") django.setup()
1.显示登陆页面
<form method="post"> {% csrf_token %}
2.处理登陆数据校验
def post(self, request): """登陆校验""" pass
username = request.POST.get("username") password = request.POST.get("pwd")
if not all([username, password]): return render(request, "login.html", {"error_msg":"数据不完整"})
user = authenticate(username=username, password=password) # 正确返回user对象,不正确返回None if user is not None: # 用户名密码正确 if user.is_active: # 用户已激活 # 将用户登陆成功后状态保存在session,使用django认证系统中的login方法 login(request, user) # 重定向到主页 return redirect(reverse("goods:index")) else: # 用户未激活 return render(request, "login.html", {"error_msg":"帐户未激活"}) else: # 用户名或密码错误 return render(request, "login.html", {"error_msg":"用户名或密码错误"})
3.进行登陆测试 ,查看网页走下方红色字样提示
AUTHENTICATION_BACKENDS = ['django.contrib.auth.backends.AllowAllUsersModelBackend']
4.配置django缓存以及session数据存储后端到redis数据库,django默认将session数据存储到mysql数据库(settings配置的数据库)中的django_session表中
pip2 install django-redis
# django缓存配置 CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/5", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } } # 使用django-redis 做为 session 储存后端 SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_CACHE_ALIAS = "default"
5.用户勾选记住用户名
# 由于redirect方法返回的是HttpResponseRedirect对象,而这个对象是HttpResponse的子类,因此能够设置cookie response = redirect(reverse("goods:index")) # 判断用户是否记勾选记住用户名 remember = request.POST.get("remember") if remember == "on": # 表示勾选了,将用户名保存在cookie中 response.set_cookie("username", username, max_age=7*24*3600) else: # 删除cookie response.delete_cookie("username") # 重定向到主页 return response
# 判断是否勾选记住用户名 if 'username' in request.COOKIES: username = request.COOKIES.get("username") checked = "checked" else: username='' checked = '' return render(request, "login.html", {"username":username, "checked":checked})
<input type="text" name="username" class="name_input" value="{{ username }}" placeholder="请输入用户名" autocomplete="off"> <input type="checkbox" name="remember" {{ checked }}>