既然有登入登出,那麼使用者的註冊肯定也是少不了的。
登錄檔單類
使用者註冊時會用到表單來提交賬號、密碼等資料,所以需要寫註冊用的表單/userprofile/forms.py
:
/userprofile/forms.py
...
# 註冊使用者表單
class UserRegisterForm(forms.ModelForm):
# 複寫 User 的密碼
password = forms.CharField()
password2 = forms.CharField()
class Meta:
model = User
fields = ('username', 'email')
# 對兩次輸入的密碼是否一致進行檢查
def clean_password2(self):
data = self.cleaned_data
if data.get('password') == data.get('password2'):
return data.get('password')
else:
raise forms.ValidationError("密碼輸入不一致,請重試。")
複製程式碼
上一章也講過,對資料庫進行操作的表單應該繼承forms.ModelForm
,可以自動生成模型中已有的欄位。
這裡我們覆寫了password
欄位,因為通常在註冊時需要重複輸入password
來確保使用者沒有將密碼輸入錯誤,所以覆寫掉它以便我們自己進行資料的驗證工作。def clean_password2()
中的內容便是在驗證密碼是否一致了。def clean_[欄位]
這種寫法Django會自動呼叫,來對單個欄位的資料進行驗證清洗。
覆寫某欄位之後,內部類class Meta
中的定義對這個欄位就沒有效果了,所以fields
不用包含password
。
需要注意:
- 驗證密碼一致性方法不能寫
def clean_password()
,因為如果你不定義def clean_password2()
方法,會導致password2中的資料被Django判定為無效資料從而清洗掉,從而password2
屬性不存在。最終導致兩次密碼輸入始終會不一致,並且很難判斷出錯誤原因。 - 從POST中取值用的
data.get('password')
是一種穩妥的寫法,即使使用者沒有輸入密碼也不會導致程式錯誤而跳出。前面章節提取POST資料我們用了data['password']
,這種取值方式如果data中不包含password
,Django會報錯。另一種防止使用者不輸入密碼就提交的方式是在表單中插入required
屬性,後面會講到。
檢視函式
編寫註冊的檢視/userprofile/views.py
:
/userprofile/views.py
# 引入 UserRegisterForm 表單類
from .forms import UserLoginForm, UserRegisterForm
# 使用者註冊
def user_register(request):
if request.method == 'POST':
user_register_form = UserRegisterForm(data=request.POST)
if user_register_form.is_valid():
new_user = user_register_form.save(commit=False)
# 設定密碼
new_user.set_password(user_register_form.cleaned_data['password'])
new_user.save()
# 儲存好資料後立即登入並返回部落格列表頁面
login(request, new_user)
return redirect("article:article_list")
else:
return HttpResponse("登錄檔單輸入有誤。請重新輸入~")
elif request.method == 'GET':
user_register_form = UserRegisterForm()
context = { 'form': user_register_form }
return render(request, 'userprofile/register.html', context)
else:
return HttpResponse("請使用GET或POST請求資料")
複製程式碼
邏輯上結合了發表文章檢視和使用者登入檢視,沒有新的知識。
使用者在註冊成功後會自動登入並返回部落格列表頁面。
模板和url
表單有關的模板檔案我們也很熟悉了,新建/templates/userprofile/register.html
:
/templates/userprofile/register.html
{% extends "base.html" %} {% load staticfiles %}
{% block title %} 登入 {% endblock title %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-12">
<br>
<form method="post" action=".">
{% csrf_token %}
<!-- 賬號 -->
<div class="form-group col-md-4">
<label for="username">暱稱</label>
<input type="text" class="form-control" id="username" name="username" required>
</div>
<!-- 郵箱 -->
<div class="form-group col-md-4">
<label for="email">Email</label>
<input type="text" class="form-control" id="email" name="email">
</div>
<!-- 密碼 -->
<div class="form-group col-md-4">
<label for="password">設定密碼</label>
<input type="password" class="form-control" id="password" name="password" required>
</div>
<!-- 確認密碼 -->
<div class="form-group col-md-4">
<label for="password2">確認密碼</label>
<input type="password" class="form-control" id="password2" name="password2" required>
</div>
<!-- 提交按鈕 -->
<button type="submit" class="btn btn-primary">提交</button>
</form>
</div>
</div>
</div>
{% endblock content %}
複製程式碼
上面的模板檔案中,我們在暱稱、密碼input
標籤中新增了required
屬性(前面提到過)。如果使用者不填寫帶有required
屬性的欄位,表單就不能提交,並提示使用者填寫。實際上前面學習的很多表單都可以新增required
屬性來提前驗證資料的有效性。
註冊的入口你可以放在任何喜歡的地方。本文放在登入頁面中/templates/userprofile/login.html
:
/templates/userprofile/login.html
...
<div class="col-12">
<br>
<h5>還沒有賬號?</h5>
<h5>點選<a href='{% url "userprofile:register" %}'>註冊賬號</a>加入我們吧!</h5>
<br>
<form method="post" action=".">
...
</form>
</div>
...
複製程式碼
最後就是在app中配置路由檔案/userprofile/urls.py
了:
/userprofile/urls.py
...
urlpatterns = [
...
# 使用者註冊
path('register/', views.user_register, name='register'),
]
複製程式碼
測試
執行伺服器,進入到登入頁面,多了註冊的提示:
點選註冊賬號進入註冊頁面:
填寫好表單後提交(Email地址是可以為空的):
成功登入並返回了部落格列表,功能完成。
總結
本章用到了表單類、對資料進行驗證清洗等知識,完成了使用者的註冊功能。
接下來學習如何實現刪除已有的使用者。
- 有疑問請在杜賽的個人網站留言,我會盡快回復。
- 或Email私信我:dusaiphoto@foxmail.com
- 專案完整程式碼:Django_blog_tutorial
轉載請告知作者並註明出處。