日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

django+xadmin在线教育平台(十二)

發布時間:2025/3/15 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 django+xadmin在线教育平台(十二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

6-4 用form實現登錄-1

上面我們的用戶登錄的方法是基于函數來做的。本節我們做一個基于類方法的版本。
要求對類的繼承有了解。

基礎教程中基本上都是基于函數來做的,其實更推薦基于類來做。基于類可以帶來不少好處

# 基于類實現需要繼承的view from django.views.generic.base import View class LoginView(View): # 直接調用get方法免去判斷 def get(self, request): # render就是渲染html返回用戶 # render三變量: request 模板名稱 一個字典寫明傳給前端的值 return render(request, "login.html", {}) def post(self, request): # 取不到時為空,username,password為前端頁面name值 user_name = request.POST.get("username", "") pass_word = request.POST.get("password", "") # 成功返回user對象,失敗返回null user = authenticate(username=user_name, password=pass_word) # 如果不是null說明驗證成功 if user is not None: # login_in 兩參數:request, user # 實際是對request寫了一部分東西進去,然后在render的時候: # request是要render回去的。這些信息也就隨著返回瀏覽器。完成登錄 login(request, user) # 跳轉到首頁 user request會被帶回到首頁 return render(request, "index.html") # 沒有成功說明里面的值是None,并再次跳轉回主頁面 else: return render(request, "login.html", {"msg": "用戶名或密碼錯誤! "}) mark

繼承的view中的方法。

django1.9.8 urls中的配置:

# 換用類實現 from users.views import LoginView# 基于類方法實現登錄,這里是調用它的方法 url('^login/$', LoginView.as_view(), name="login")

Django2.0.1 urls配置:

# 基于類方法實現登錄,這里是調用它的方法path('login/', LoginView.as_view(), name="login")

6-5 form字段驗證

驗證最大長度,是否為空等一系列。

users下新建forms文件。

# encoding: utf-8 __author__ = 'mtianyan' __date__ = '2018/1/10 0010 04:44' # 引入Django表單 from django import forms # 登錄表單驗證 class LoginForm(forms.Form): # 用戶名密碼不能為空 username = forms.CharField(required=True) password = forms.CharField(required=True, min_length=5)

定義好forms之后我們來使用它做驗證。

def post(self, request): # 類實例化需要一個字典參數dict:request.POST就是一個QueryDict所以直接傳入 # POST中的usernamepassword,會對應到form中 login_form = LoginForm(request.POST) #is_valid判斷我們字段是否有錯執行我們原有邏輯,驗證失敗跳回login頁面 if login_form.is_valid(): # 取不到時為空,username,password為前端頁面name值 user_name = request.POST.get("username", "") pass_word = request.POST.get("password", "") # 成功返回user對象,失敗返回null user = authenticate(username=user_name, password=pass_word) # 如果不是null說明驗證成功 if user is not None: # login_in 兩參數:request, user # 實際是對request寫了一部分東西進去,然后在render的時候: # request是要render回去的。這些信息也就隨著返回瀏覽器。完成登錄 login(request, user) # 跳轉到首頁 user request會被帶回到首頁 return render(request, "index.html") # 驗證不成功跳回登錄頁面 # 沒有成功說明里面的值是None,并再次跳轉回主頁面 else: return render(request, "login.html", {"msg": "用戶名或密碼錯誤! "})

完善錯誤提示

比如:既然表單都驗證失敗了,就不用顯示密碼出錯了

mark # 僅當用戶真的密碼出錯時else:return render(request, "login.html",{"msg":"用戶名或密碼錯誤!"}) # 驗證不成功跳回登錄頁面 # 沒有成功說明里面的值是None,并再次跳轉回主頁面 else: return render( request, "login.html", { "login_form": login_form })

forms中的名稱username和password必須和html中的一致。畢竟他是使用的request.POST
而request是從前面傳過來的。

實例化LoginView時已經對于我們的字段進行了驗證。

打上斷點:

mark

debug后f6運行到

mark

此時可以看到errors(ErrorDict)中的錯誤

mark

將form傳回前端:

mark

前端中取值:

mark

給這個class加上errorput會顯示紅色外框。

mark

注意:寫在class里面

將forms錯誤信息顯示出來

<div class="error btns login-form-tips" id="jsLoginTips"> {% for key, error in login_form.errors.items %} {{ error }} {% endfor %} {{ msg }}</div> mark
  • 寫了一個類繼承Django的view,然后寫了get post方法(get/post的if是Django替我們完成的)
  • 在url中調用Loginview的as_view方法需要加上括號,進行調用。
  • Django的form進行表單驗證并把error值傳到前臺。
  • is_valid方法,驗證表單

本小節完畢對應commit:

6-4 & 5 登錄換用類繼承view實現,使用Django form進行表單驗證并把錯誤信息提示到前臺。

6-6 session和cookie自動登錄機制

我們本節來講session和cookie

User1如何實現登錄的。

cookie的存儲

cookie是瀏覽器支持的一種本地存儲方式。以dict,鍵值對方式存儲。

{"sessionkey": "123"}

瀏覽器會自動對于它進行解析。

http請求是一種無狀態的請求

用戶向服務器發起的兩次請求之間是沒有狀態的。也就是服務器并不知道這是同一個用戶發的。

做到記住用戶:

瀏覽器a在向服務器發起請求,服務器會自動給瀏覽器a回復一個id,瀏覽器a把id放到cookie當中,在下一次請求時帶上這個cookie里的id值向瀏覽器請求,服務器就知道你是哪個瀏覽器發過來的了。

有狀態請求(cookie)

mark

服務器a發回來的id會放到服務器a的域之下。不能跨域訪問cookie。

使用瀏覽器隨便打開一個網頁,然后f12打開。

比如我使用的Chrome瀏覽器

mark

會找到存儲在瀏覽器本地的cookie值

mark

點擊clear all清空所有的cookie f5刷新頁面,會發現又把這些cookie值進來。

如果將用戶名和密碼直接保存在cookie,可以實現最垃圾最簡略版本的自動登錄。

解決cookie放在本地不安全的問題(session)

用戶在第一次請求后,瀏覽器回復的id既可以是用戶的user id。
也可以一段任意的字符串,我們把它叫做session id

根據用戶名和密碼,服務器會采用自己的規則生成session id。這個session id保存在本地cookie。瀏覽器請求服務器會攜帶。

  • 輸入用戶名 & 密碼
  • 調用 login(), 后端程序會根據用戶名密碼生成session id。保存在數據庫中。
  • 用戶登錄之后,需要通過這個session id取出這些基本信息。
mark

Django的默認表中的session表就記錄了用戶登錄時,后端我們Django為用戶生成的sessionid。

mark

可以看到session key value 和過期時間。

我們可以清空這張表的數據。運行項目進行登錄。

mark

可以看到我們剛剛生成的session id。

此時通過f12查看瀏覽器在本地存儲的session id。可以看到如下圖和我們數據庫中的一致。

mark

session_key 發到瀏覽器叫做session id

通過session id 用戶訪問任何一個頁面都會攜帶,服務器就會認識。

Setting.py中,

mark

這個app會攔截我們每次的request請求,在request中找到session id,然后去數據表中進行查詢。
然后通過session key 去找到session data。此時直接為我們取出了user。

在服務器返回瀏覽器的response中也會直接加上session id

cookie是瀏覽器本地存儲機制,存在域名之下,存儲不安全。
服務器在返回id時通過規則生成一串字符,并設置了過期時間。存儲在服務器端(數據庫)

文章: http://projectsedu.com/2016/10/17/django%E4%BB%8E%E8%AF%B7%E6%B1%82%E5%88%B0%E8%BF%94%E5%9B%9E%E9%83%BD%E7%BB%8F%E5%8E%86%E4%BA%86%E4%BB%80%E4%B9%88/

6-7 用戶注冊

拷貝注冊頁面進入template目錄

書寫我們對應要處理的view(RegisterView)

users/views.py

# 注冊功能的view class RegisterView(View): # get方法直接返回頁面 def get(self, request): return render(request, "register.html", {})

配置對應的url

Django1.9.8 url配置如下:

from users.views import RegisterView# 注冊urlurl("^register/", RegisterView.as_view(), name="register"),

Django2.0.1 url配置如下

from users.views import RegisterView# 注冊urlpath("register/", RegisterView.as_view(), name = "register" )

修改index頁面中注冊url

mark

此時訪問首頁發現可以成功跳轉到注冊頁面

修改靜態文件中static目錄引用

關鍵步驟load staticfile

mark

然后修改路徑為一個相對于static的相對路徑

mark

他會自動根據setting中配置,為我們加上前綴

mark

如果我們把目錄在setting中改到mystatic。url中會自動添加指定的前綴

可以看到可以訪問成功。

mark

將目前的三個html中的靜態文件全部修改目錄

枯燥但是要有耐心。

這時候訪問三個頁面,查看樣式是否完好。

驗證碼庫實現驗證碼

https://github.com/mbi/django-simple-captcha

安裝配置

workon mxonline3 pip install django-simple-captcha workon mxonline2 pip install django-simple-captcha==0.4.6
  • Add captcha to the INSTALLED_APPS in your settings.py

  • Add an entry to your urls.py:

django1.9.8如下:

from django.conf.urls import url, include urlpatterns += [url(r'^captcha/', include('captcha.urls')), ]

django2.0.1如下;

# 驗證碼urlpath("captcha/", include('captcha.urls')) makemigrations migrate mark

進入數據庫查看生成的表

mark mark

將驗證碼展示到頁面

users/forms.py:

定義我們的register form:

# 引入驗證碼field from captcha.fields import CaptchaField# 驗證碼form & 注冊表單form class RegisterForm(forms.Form): # 此處email與前端name需保持一致。 email = forms.EmailField(required=True) # 密碼不能小于5位 password = forms.CharField(required=True, min_length=5) # 應用驗證碼 captcha = CaptchaField()

users/views.py

在我們的registerform中實例化并傳送到前端:

# form表單驗證 & 驗證碼 from .forms import LoginForm, RegisterForm# 注冊功能的view class RegisterView(View): # get方法直接返回頁面 def get(self, request): # 添加驗證碼 register_form = RegisterForm() return render(request, "register.html", {'register_form':register_form})

前端獲取驗證碼值

mark mark

找到上圖驗證碼部分。修改為下圖

mark

Forms中的field會生成不同的框。

mark

我們只有label但是前端可以查看到input框等,也就是Registerform會為我們生成輸入框+驗證碼。

隱藏的字符串的框會被帶到后臺,由Django為我們進行驗證。驗證該驗證碼是否保存過。

mark

可以看得我們數據庫中將這個hashkey進行了保存。這個key與驗證碼內容對應。

后臺會把驗證碼值 和 hashkey進行聯合查詢。

編寫register view的后臺邏輯(RegisterView)

users/views.py的RegisterView中添加post方法:

def post(self, request): # 實例化form register_form = RegisterForm(request.POST) if register_form.is_valid(): pass mark mark

修改form表單提交方式與提交到哪個url

mark

前端的form提交加上對應的crsf token

刷新驗證碼是前端幫我們完成的:

//刷新驗證碼 function refresh_captcha(event){ $.get("/captcha/refresh/?"+Math.random(), function(result){ $('#'+event.data.form_id+' .captcha').attr("src",result.image_url); $('#id_captcha_0').attr("value",result.key); }); return false; }

獲取前端頁面值并封裝成一個user_profile對象,保存到數據庫。

from django.contrib.auth.hashers import make_passwordif register_form.is_valid():user_name = request.POST.get("email", "") pass_word = request.POST.get("password", "") # 實例化一個user_profile對象,將前臺值存入 user_profile = UserProfile() user_profile.username = user_name user_profile.email = user_name # 加密password進行保存 user_profile.password = make_password(pass_word) user_profile.save() pass

發送郵件實現

setting中配置;

# 發送郵件的setting設置EMAIL_HOST = "smtp.qq.com" EMAIL_PORT = 25 EMAIL_HOST_USER = "mxonline.mtianyan.cn" EMAIL_HOST_PASSWORD = " " EMAIL_USE_TLS= True EMAIL_FROM = "mxonline.mtianyan.cn"

新建package后新建文件。

apps:utils/email_send.py:

# encoding: utf-8 from random import Random__author__ = 'mtianyan' __date__ = '2018/1/10 0010 20:47' from users.models import EmailVerifyRecord # 導入Django自帶的郵件模塊 from django.core.mail import send_mail # 導入setting中發送郵件的配置 from Mxonline2.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 = "mtianyan慕課小站 注冊激活鏈接" 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 mark

上圖為qq郵箱開啟smtp服務

點擊生成授權碼

mark

def post中加上發送郵件

users/views.py:

# 發送郵件 from utils.email_send import send_register_eamil# 發送注冊激活郵件 send_register_eamil(user_name, "register")

點擊注冊提交,因為我們沒有return。一直在轉圈圈。

但是數據庫中已經添加了字段。

mark

可以看到我們的郵件已經被發送到郵箱中。

如果注冊成功返回login頁面:不成功,返回register頁面并報錯。

完善錯誤提示。

找貓畫虎:將login中的錯誤提示搬運到register中來。

  • register_form的報錯信息。
mark mark
  • 郵箱 & 密碼 form驗證
mark

完善用戶值回填邏輯

mark

如果傳回的有值則,顯示傳回來值。

密碼也做同樣操作

修改默認的激活狀態為false

post方法中

# 默認激活狀態為falseuser_profile.is_active = False

書寫處理激活的view。

# 激活用戶的view class ActiveUserView(View): def get(self, request, active_code): # 查詢郵箱驗證記錄是否存在 all_record = EmailVerifyRecord.objects.filter(code = active_code) # 激活form負責給激活跳轉進來的人加驗證碼 active_form = ActiveForm(request.GET) # 如果不為空也就是有用戶 if all_record: for record in all_record: # 獲取到對應的郵箱 email = record.email # 查找到郵箱對應的user user = UserProfile.objects.get(email=email) user.is_active = True user.save() # 激活成功跳轉到登錄頁面 return render(request, "login.html", ) # 自己瞎輸的驗證碼 else: return render(request, "register.html", {"msg": "您的激活鏈接無效","active_form": active_form})

配置用戶激活的url并通過url提取到變量:

django1.9.8:

# 激活用戶urlurl(r'^active/(?P<active_code>.*)/$',ActiveUserView.as_view(), name= "user_active")

django2.0.1:

# 激活用戶urlre_path('active/(?P<active_code>.*)/', ActiveUserView.as_view(), name= "user_active")

這里通過?p將后面.*代表全部提取的正則,符合的內容傳入參數active_code中/$代表以/$為結尾

mark

其他細節根據自己需要進行優化。

注冊功能制作完畢。對應commit:

注冊功能實現完畢,流程:注冊,發郵件,激活,登錄。對應6-6,7,8,9,10



原文學習來自簡書,作者:天涯明月笙
鏈接:https://www.jianshu.com/p/9c621518d991

轉載于:https://www.cnblogs.com/xinjie57/p/9232627.html

總結

以上是生活随笔為你收集整理的django+xadmin在线教育平台(十二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。