既然有登錄登出,那麼用戶的註冊肯定也是少不了的。
註冊表單類
用戶註冊時會用到表單來提交賬號、密碼等數據,所以需要寫註冊用的表單/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('password'):
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/login.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私信我:[email protected]
- 項目完整代碼:Django_blog_tutorial
轉載請告知作者並註明出處。