說明:該篇博客是博主一字一碼編寫的,實屬不易,請尊重原創,謝謝你們!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 }}>