django如何實(shí)現(xiàn)用戶的注冊、登錄、注銷功能
創(chuàng)建django項(xiàng)目的步驟:Django項(xiàng)目的創(chuàng)建步驟
一、前置工作
配置數(shù)據(jù)庫,設(shè)置數(shù)據(jù)庫引擎為mysql
1、在settings文件中找到DATABASES, 配置以下內(nèi)容
DATABASES = {
"default": {
'ENGINE': 'django.db.backends.mysql', # 數(shù)據(jù)庫引擎
'NAME': 'django_test', # 連接的數(shù)據(jù)庫, 一定要存在
'HOST': '127.0.0.1', # mysql的ip地址, 這里是本地
'PORT': 3306, # mysql的默認(rèn)端口
'USER': 'root', # mysql的用戶名
'PASSWORD': 'xxx' # mysql的密碼
}
}
可能會提示以下內(nèi)容:

安裝即可: pip install mysqlclient -i https://pypi.tuna.tsinghua.edu.cn/simple
二、編寫用戶模型
django中使用ORM來存數(shù)據(jù)到數(shù)據(jù)庫
ORM模型(對象關(guān)系映射):
- 一個 模型類對應(yīng)數(shù)據(jù)庫中的一張表
- 一個屬性對應(yīng)數(shù)據(jù)庫中的一個字段
用戶表的字段:用戶名、密碼(可以自己擴(kuò)展)
1、用戶模型

2、創(chuàng)建好模型后要執(zhí)行遷移數(shù)據(jù)的命令:
- 生成遷移文件:python manage.py makemigrations
- 遷移生效(同步到數(shù)據(jù)庫):python manage.py migrate


3、遷移成功后,migrations文件夾下會出現(xiàn)遷移文件,該文件記錄著模型的相關(guān)信息,001表示第一次遷移.

三、編寫表單校驗(yàn),以注冊表單校驗(yàn)為例
使用django自帶的Form類來實(shí)現(xiàn)校驗(yàn)
1、對字段的校驗(yàn),這里只截了用戶名的校驗(yàn),其他字段都差不多

2、對整個表單的校驗(yàn):
User需要從models.py文件中導(dǎo)入

3、form表單中自定義的其他方法:

四、編寫前端頁面,純html,文件寫在templates文件夾中
使用了模板的方式嵌入數(shù)據(jù)
超鏈接的跳轉(zhuǎn)連接:{% url "命名空間:路由的name值" %},有命名空間一定要標(biāo)注命名空間,沒有則:{% url "路由的name值" %}
1、index.html

2、register.html
- form.non_field_errors:表當(dāng)校驗(yàn)時,表單的錯誤,就是forms.py文件中的raise forms.ValidationError("錯誤信息")。
- form.errors.username: 表單校驗(yàn)時,用戶名的錯誤,就是forms.py文件中的error_messages信息,密碼校驗(yàn)也是如此。

3、login.html

五、編寫視圖類來實(shí)現(xiàn)登錄、注冊功能
如果是get請求就執(zhí)行g(shù)et方法,是post請求就執(zhí)行post方法,在form標(biāo)簽中的methos方法中可以指定。
- form.is_valid():用來校驗(yàn)表單,校驗(yàn)成功返回True, 失敗則返回False。
- post的方法的實(shí)例化表單對象:實(shí)例化表單對象時一定要加request.POST,否則拿不到數(shù)據(jù)。
- redirect: 重定向到其他視圖函數(shù)。
- form對象:實(shí)例化表單對象,用來進(jìn)行表單的各種存在,校驗(yàn),錯誤信息等待
- request.session['username'] = request.POST['username']: 設(shè)置session值為用戶名(其他值也可以)

六、編寫首頁和注銷視圖函數(shù)
1、首頁函數(shù)
request.session.get():通過注冊時設(shè)置的session中來獲取用戶,通過這個判斷是否有登錄的用戶,可以與前端交互,有的話就顯示注銷,沒有的話顯示注冊和登錄

2、注銷函數(shù)
清除session值即可

七、編寫路由
1、在主路由中include分路由,并設(shè)置命名空間
命名空間:當(dāng)有多個應(yīng)用時建議用, 能更好的區(qū)分各個應(yīng)用,使用namespace關(guān)鍵字設(shè)置

2、在app下創(chuàng)建一個urls.py文件,編寫以下內(nèi)容
注意:一定要加app_name, 視圖類一定要加.as_view()

八、django自帶的管理后臺
使用python manage.py createtsuperuser創(chuàng)建超級用戶
1、在admin.py文件中注冊模型
- list_display:在后臺管理中要顯示的字段
- admin.site.site_header:后臺管理的標(biāo)題

2、在模型(models.py)中添加

3、使用注冊的超級用戶登錄


九、具體的文件
1、models.py
from django.db import models
class User(models.Model):
# 定義變量,對應(yīng)數(shù)據(jù)庫的表的字段
# username參數(shù):參數(shù)1:后臺管理顯示的內(nèi)容,參數(shù)2:最大長度, CharField類型必須指定,參數(shù)3:不能為空,參數(shù)4:唯一
username = models.CharField('用戶名', max_length=10, null=False, unique=True)
password = models.CharField('密碼', max_length=255, null=False)
# create_time參數(shù):參數(shù)2:記錄數(shù)據(jù)第一次創(chuàng)建的時間,自動記錄到數(shù)據(jù)庫
create_time = models.DateTimeField('注冊時間', auto_now_add=True)
# 設(shè)置后臺管理
class Meta:
app_label = 'app' # 屬于那個app
verbose_name = '用戶'
verbose_name_plural = verbose_name
# 輸出對象時用到的
def __str__(self):
return self.username2、forms.py
from django import forms
from .models import User
class RegisterForm(forms.Form):
# 用戶名
username = forms.CharField(
required=True, # 不能為空,必須
max_length=10, # 最大長度
min_length=4, # 最小長度
error_messages={
'required': "不能為空",
'max_length': "長度不能大于10",
'min_length': "長度不能小于4",
}
)
# 密碼
password = forms.CharField(
required=True, # 不能為空,必須
max_length=16, # 最大長度
min_length=8, # 最小長度
error_messages={
'required': "不能為空",
'max_length': "長度不能大于16",
'min_length': "長度不能小于8",
}
)
# 校驗(yàn)
def clean(self):
# 獲取輸入的用戶名
username = self.cleaned_data.get('username')
user = User.objects.filter(username=username) # 獲得一個查詢集,可以理解為一個列表
# 用戶存在
if user.exists():
raise forms.ValidationError("用戶已存在")
return self.cleaned_data
# 存入數(shù)據(jù)庫
def save(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
# 存入數(shù)據(jù)庫
user = User(username=username, password=password)
user.save()
class LoginForm(forms.Form):
# 用戶名
username = forms.CharField(
required=True, # 不能為空,必須
max_length=10, # 最大長度
min_length=4, # 最小長度
error_messages={
'required': "不能為空",
'max_length': "長度不能大于10",
'min_length': "長度不能小于4",
}
)
# 密碼
password = forms.CharField(
required=True, # 不能為空,必須
max_length=16, # 最大長度
min_length=8, # 最小長度
error_messages={
'required': "不能為空",
'max_length': "長度不能大于16",
'min_length': "長度不能小于8",
}
)
# 校驗(yàn)
def clean(self):
# 獲取輸入的信息
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
user = User.objects.filter(username=username) # 獲得一個查詢集,可以理解為一個列表
if user.exists():
if user[0].password != password:
raise forms.ValidationError("密碼錯誤")
else:
raise forms.ValidationError("用戶不存在")
return self.cleaned_data3、admin.py
from django.contrib import admin
from .models import User
# Register your models here.
@admin.register(User)
class UserAdmin(admin.ModelAdmin):
list_display = ['id', 'username', 'create_time']
admin.site.site_header = 'django后臺管理'4、views.py
from django.shortcuts import render, HttpResponse, redirect
from django.views import View
from .models import User
from .forms import RegisterForm, LoginForm
# Create your views here.
def index(request):
username = request.session.get('username', default=0) # 通過session獲取用戶名,給默認(rèn)值防止報(bào)錯
user = User.objects.filter(username=username).first()
return render(request, 'index.html', {'user': user})
class RegisterView(View):
def get(self, request):
form = RegisterForm()
return render(request, 'register.html', {'form': form})
def post(self, request):
form = RegisterForm(request.POST)
if form.is_valid():
form.save()
return redirect('app:login')
return render(request, 'register.html', {'form': form})
class LoginView(View):
def get(self, request):
form = LoginForm()
return render(request, 'login.html', {'form': form})
def post(self, request):
form = LoginForm(request.POST)
print("登錄")
if form.is_valid():
# 設(shè)置session
request.session['username'] = request.POST['username']
return redirect('app:index')
return render(request, 'login.html', {'form': form})
# 注銷
def Logout(request):
request.session.clear() # 清除session
return redirect('app:index')
5、app中的urls.py
from django.urls import path
from .views import *
app_name = 'app'
urlpatterns = [
path('', index, name='index'), # 首頁
path('register/', RegisterView.as_view(), name='register'), # 注冊
path('login/', LoginView.as_view(), name='login'), # 登錄
path('logout', Logout, name='logout'), # 注銷
]6、主路由urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls),
path('', include('app.urls', namespace='app'))
]7、index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首頁</title>
</head>
<body>
{% if user %}
<h1>歡迎{{ user.username }}進(jìn)入首頁?。。?lt;/h1>
<a href="{% url 'app:logout' %}" rel="external nofollow" >注銷</a>
{% else %}
<h1>請注冊或登錄</h1>
<a href="{% url 'app:register' %}" rel="external nofollow" rel="external nofollow" >注冊</a>
<a href="{% url 'app:login' %}" rel="external nofollow" rel="external nofollow" >登錄</a>
{% endif %}
</body>
</html>8、register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注冊</title>
</head>
<body>
<h3>注冊</h3>
<a href="{% url 'app:login' %}" rel="external nofollow" rel="external nofollow" >登錄</a>|
<a href="{% url 'app:index' %}" rel="external nofollow" rel="external nofollow" >首頁</a>
<form action="{% url 'app:register' %}" method="post">
{% csrf_token %}
<div><p style="color: red">{{ form.non_field_errors }}</p></div>
<div>
<lable>用戶名</lable>
<label>
<input type="text" name="username">
</label>
<p style="color: red">{{ form.errors.username }}</p>
</div>
<div>
<lable>密碼</lable>
<label>
<input type="password" name="password">
<p style="color: red">{{ form.errors.password }}</p>
</label>
</div>
<button type="submit">注冊</button>
</form>
</body>
</html>9、login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄</title>
</head>
<body>
<h3>登錄</h3>
<a href="{% url 'app:register' %}" rel="external nofollow" rel="external nofollow" >注冊</a>|
<a href="{% url 'app:index' %}" rel="external nofollow" rel="external nofollow" >首頁</a>
<form action="{% url 'app:login' %}" method="post">
{% csrf_token %}
<div><p style="color: red">{{ form.non_field_errors }}</p></div>
<div>
<lable>用戶名</lable>
<label>
<input type="text" name="username">
<p style="color: red">{{ form.errors.username }}</p>
</label>
</div>
<div>
<lable>密碼</lable>
<label>
<input type="password" name="password">
<p style="color: red">{{ form.errors.password }}</p>
</label>
</div>
<button>登錄</button>
</form>
</body>
</html>總結(jié)
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
- django authentication 登錄注冊的實(shí)現(xiàn)示例
- Django 登錄注冊的實(shí)現(xiàn)示例
- Python基于Django實(shí)現(xiàn)驗(yàn)證碼登錄功能
- 利用django和mysql實(shí)現(xiàn)一個簡單的web登錄頁面
- Django通過自定義認(rèn)證后端實(shí)現(xiàn)多種登錄方式驗(yàn)證
- Django實(shí)現(xiàn)簡單登錄的示例代碼
- Django實(shí)現(xiàn)前后端登錄
- Django中使用pillow實(shí)現(xiàn)登錄驗(yàn)證碼功能(帶刷新驗(yàn)證碼功能)
- 給Django Admin添加驗(yàn)證碼和多次登錄嘗試限制的實(shí)現(xiàn)
- 使用Tastypie登錄Django的問題解決
相關(guān)文章
淺談JupyterNotebook導(dǎo)出pdf解決中文的問題
這篇文章主要介紹了淺談JupyterNotebook導(dǎo)出pdf解決中文的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-04-04
JavaScript中的模擬事件和自定義事件實(shí)例分析
這篇文章主要介紹了JavaScript中的模擬事件和自定義事件,結(jié)合實(shí)例形式分析了JavaScript模擬事件和自定義事件相關(guān)操作步驟、實(shí)現(xiàn)技巧與注意事項(xiàng),需要的朋友可以參考下2018-07-07
python高溫預(yù)警數(shù)據(jù)獲取實(shí)例
這篇文章主要為大家介紹了利用python獲取高溫?cái)?shù)據(jù)進(jìn)行高溫預(yù)警的防護(hù)措施,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Pyqt5 關(guān)于流式布局和滾動條的綜合使用示例代碼
這篇文章主要介紹了Pyqt5 關(guān)于流式布局和滾動條的綜合使用示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
一文帶你深入理解python中pytest-repeat插件的工作原理
這篇文章主要和大家一起深入探討到底pytest_repeat插件的具體功能是如何實(shí)現(xiàn)的呢,相信具體了解了該插件,其他三方插件也可以很快了解它內(nèi)部運(yùn)行機(jī)制,所以本文詳細(xì)講解了python pytest-repeat插件的工作原理,需要的朋友可以參考下2023-09-09
Python3 XML 獲取雅虎天氣的實(shí)現(xiàn)方法
下面小編就為大家分享一篇Python3 XML 獲取雅虎天氣的實(shí)現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02

