用戶註冊登陸是一個網站的基本功能,django對這部分進行了很好的封裝,咱們只須要在django的基礎上作些簡單的修改就能夠達到咱們想要的效果。在本講中,咱們會用到user中的用戶受權方面的一些函數,還會對django中的user進行擴展,以及django中的form驗證。html
註冊頁面 前端
登陸頁面 python
django的設計哲學是,一個應用只提供一種功能,好比users應用只提供用戶相關功能,comment應用只提供評論相關功能,這能提升代碼的重複利用率。git
在django中,只須要下面一條命令,便可創建users應用github
python3 manage.py startapp users
複製代碼
咱們須要一個用戶表,用來實現登陸註冊功能,雖然django已經自帶來用戶登陸註冊功能,也有相應的表,可是不符合中國人習慣,須要咱們對user模型進行自定義。實現自定義User模型最簡單的方式就是繼承AbstractBaseUser,AbstractBaseUser實現了User的核心功能,咱們只需加一些額外的字段進行補充便可。django
User模型原有的字段有:bash
這些都是最基本的字段,並不能知足咱們的需求。app
根據網站自身業務,咱們又添加了下面的字段ide
咱們只需在users/models.py中寫入代碼函數
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
GENDER_CHOICES = (
('M', '男'),
('F', '女'),
)
nickname = models.CharField(blank=True, null=True, max_length=20)
avatar = models.FileField(upload_to='avatar/')
mobile = models.CharField(blank=True, null=True, max_length=13)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES,blank=True, null=True)
subscribe = models.BooleanField(default=False)
class Meta:
db_table = "v_user"
複製代碼
gender是性別字段,其中用到了choices=GENDER_CHOICES。這種方式經常用在下拉框或單多選框,例如 M對應男 F對應女。
在user文件夾下面,新建url.py文件,寫入登陸、註冊和退出的url信息。app_name是命名空間,咱們命名爲'users'。
from django.urls import path
from . import views
app_name = 'users'
urlpatterns = [
path('login/', views.login, name='login'),
path('signup/', views.signup, name='signup'),
path('logout/', views.logout, name='logout'),
]
複製代碼
url路由配置好了,咱們下面就開始寫視圖函數代碼了
咱們先來寫註冊函數,寫註冊,固然得有註冊表單了,幸運的是,在django中,能夠用代碼來生成表單。咱們只需在users下新建forms.py文件,而後寫入註冊表單的代碼。
class SignUpForm(UserCreationForm):
username = forms.CharField(min_length=4,max_length=30,
error_messages={
'min_length': '用戶名很多於4個字符',
'max_length': '用戶名不能多於30個字符',
'required': '用戶名不能爲空',
},
widget=forms.TextInput(attrs={'placeholder': '請輸入用戶名'}))
password1 = forms.CharField(min_length=8, max_length=30,
error_messages={
'min_length': '密碼很多於8個字符',
'max_length': '密碼不能多於30個字符',
'required': '密碼不能爲空',
},
widget=forms.PasswordInput(attrs={'placeholder': '請輸入密碼'}))
password2 = forms.CharField(min_length=8,max_length=30,
error_messages={
'min_length': '密碼很多於8個字符',
'max_length': '密碼不能多於30個字符',
'required': '密碼不能爲空',
},
widget=forms.PasswordInput(attrs={'placeholder': '請確認密碼'}))
class Meta:
model = User
fields = ('username', 'password1', 'password2',)
error_messages = {'password_mismatch': '兩次密碼不一致', }
複製代碼
咱們的表單一共有三個字段:username、password一、password2,它們都是CharField類型,widget分別是TextInput和PasswordInput。並且django是自帶驗證的,只須要咱們配置好error_messages字典,當form驗證的時候,就會顯示咱們自定義的錯誤信息。 有了註冊表單後,就能夠在前端模板和視圖函數中使用它。
下面是註冊視圖函數。
...
from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
raw_password1 = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password1)
auth_login(request, user)
return redirect('home')
else:
print(form.errors)
else:
form = SignUpForm()
return render(request, 'registration/signup.html', {'form': form})
複製代碼
在signup函數中,咱們經過form = SignUpForm初始化一個表單,並在render函數中傳遞給模板。
註冊模板文件寫在了templates/registration/signup.html
關鍵代碼是
<form class="ui large form" novalidate method="post" action="{% url 'users:signup' %}" enctype="multipart/form-data" >
{% csrf_token %}
<div class="ui stacked segment">
<div class="field">
{{form.username}}
</div>
<div class="field">
{{form.password1}}
</div>
<div class="field">
{{form.password2}}
</div>
<button class="ui submit button" type="submit">註冊</button>
</div>
{% include "base/form_errors.html" %}
</form>
複製代碼
form的action爲
{% url 'users:signup' %}
複製代碼
即在url.py中定義的signup函數。 經過post請求傳遞給signup,在signup中,經過以下四行代碼來實現註冊,並自動登陸的。
username = form.cleaned_data.get('username')
raw_password1 = form.cleaned_data.get('password1')
user = authenticate(username=username, password=raw_password1)
auth_login(request, user)
複製代碼
登陸函數與註冊函數的模式是同樣的,都是先寫form,寫模板,最後寫視圖函數。 因爲form和模板的代碼和註冊功能相似,這裏就不貼了,你們能夠上github查看。
重點講一下login視圖函數
def login(request):
if request.method == 'POST':
next = request.POST.get('next', '/')
form = UserLoginForm(request=request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
auth_login(request, user)
return redirect(next)
else:
print(form.errors)
else:
next = request.GET.get('next', '/')
form = UserLoginForm()
print(next)
return render(request, 'registration/login.html', {'form': form, 'next':next})
複製代碼
在login函數中,咱們多了一個next變量,next對應的是登陸後要跳轉的url,其實這是一種場景,假如你在購物網站買東西,最後付款的時候,會跳轉到付款頁,假如你沒有登陸,網站會提示你登陸,登陸後,會再次跳轉到付款頁。
固然了,跳轉到登陸頁的時候,須要你在url後追加next參數,如 aaa. com/login/?next=bbb. com 這樣用戶登陸後就會跳到bbb. com
from django.contrib.auth import authenticate, login as auth_login, logout as auth_logout
def logout(request):
auth_logout(request)
return redirect('home')
複製代碼
退出功能,僅須要一行代碼 auth_logout(request) 就ok了。