Django Login 实现
Django 提供了强大的认证系统,可以用来轻松地实现用户登录、注册、登出等功能。在这里,我们将通过创建一个简单的登录功能来演示如何在 Django 中实现用户认证。
1. 创建 Django 项目和应用
首先,确保你已经安装了 Django,并且创建了一个新的项目和应用。
django-admin startproject testproject
cd testproject
python manage.py startapp login
2. 配置 settings.py
2.1 添加 login
应用到 INSTALLED_APPS
在 testproject/settings.py
中,将 login
应用添加到 INSTALLED_APPS
列表中:
INSTALLED_APPS = [
'django.contrib.auth', # Django 的认证系统
'login', # 登录应用
]
2.2 配置登录重定向(为验证)
在 settings.py
中,配置成功登录后的重定向 URL:
LOGIN_REDIRECT_URL = '/' # 登录成功后重定向到首页
LOGOUT_REDIRECT_URL = '/' # 登出后重定向到首页
2.3配置登录模版路径
配置TEMPLATES的 DIRS为 [BASE_DIR / ‘templates’]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
3. 创建用户登录视图
3.1 在 login/views.py
中创建登录视图, 这里使用了Django 的验证系统。
# login/views.py
from django.shortcuts import render,redirect
from .forms import CustomAuthenticationForm
from django.contrib.auth import authenticate, login
def login_view(request):
if request.method == 'POST':
form = CustomAuthenticationForm(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:
login(request, user)
return redirect('home') # 登录成功后重定向到主页
else:
form = CustomAuthenticationForm()
return render(request, 'login.html', {'form': form})
4. 创建登录模板
在 testproject/templates/
文件夹中创建 login.html
模板文件。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>登录页面</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f8f9fa;
}
.login-container {
max-width: 400px;
margin: 100px auto;
}
.login-card {
padding: 30px;
border-radius: 8px;
background-color: white;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.form-title {
margin-bottom: 20px;
text-align: center;
font-size: 24px;
font-weight: bold;
}
</style>
</head>
<body>
<div class="login-container">
<div class="login-card">
<div class="form-title">
登录
</div>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<div class="d-grid">
<button type="submit" class="btn btn-primary">登录</button>
</div>
</form>
<div class="text-center mt-3">
<a href="#">忘记密码?</a> | <a href="#">注册账户</a>
</div>
</div>
</div>
<!-- 引入Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.11.6/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
</body>
</html>
4.1 自定义登录表单
创建一个登录表单并在视图中使用。例如,创建一个 forms.py
来定义表单:
from django import forms
from django.contrib.auth.forms import AuthenticationForm
class CustomAuthenticationForm(AuthenticationForm):
username = forms.CharField(
max_length=100,
label="用户名",
widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': '请输入用户名'})
)
password = forms.CharField(
widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': '请输入密码'}),
label="密码"
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].error_messages = {'required': '用户名不能为空'}
self.fields['password'].error_messages = {'required': '密码不能为空'}
然后在视图中使用这个表单
5. URL 配置
5.1在 login 创建 urls.py
# login/urls.py
from django.urls import path
from .views import login_view
urlpatterns = [
path('', login_view),
]
5.2在 login 创建 urls.py
将app urls 关联到主项目
# ocpptest/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', include('login.urls')),
]
6. 运行服务器
完成上述步骤后,运行开发服务器并访问登录页面:
python manage.py runserver
-
登录:访问
/login/
-
-
注册(注册实现):访问
/login/register/
Register实现
django.contrib.auth 自带了一套验证体系,包括身份验证和授权以及注册。可以直接使用UserCreationForm 创建用户
注册视图
def register_view(request):
if request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save() # 注册新用户
messages.success(request, 'Your account has been created successfully! You can now log in.')
return redirect('login') # 注册成功后重定向到登录页面
else:
messages.error(request, form.errors)
else:
form = UserCreationForm() # GET 请求时传递空的表单对象, 这里有bug,后续xiufu
return render(request, 'register.html', {'form': form})
配置路由
path('register/', register_view, name='register'),
编辑注册页面
实际实现可以裁分,提升模版复用率
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>注册页面</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f8f9fa;
font-family: 'Arial', sans-serif;
}
/* 主容器 */
.login-container {
max-width: 450px;
margin: 100px auto;
}
/* 卡片样式 */
.login-card {
padding: 30px;
border-radius: 8px;
background-color: white;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
.form-title {
margin-bottom: 20px;
text-align: center;
font-size: 28px;
font-weight: bold;
color: #333;
}
.form-group {
margin-bottom: 15px;
}
.form-control {
border-radius: 5px;
padding: 10px;
font-size: 16px;
}
/* 按钮样式 */
.btn-primary {
background-color: #007bff;
border: none;
border-radius: 5px;
padding: 12px 20px;
font-size: 16px;
width: 100%;
transition: background-color 0.3s ease;
}
.btn-primary:hover {
background-color: #0056b3;
}
.text-muted {
font-size: 14px;
text-align: center;
color: #6c757d;
}
.text-muted a {
color: #007bff;
}
.text-muted a:hover {
text-decoration: underline;
}
.messages {
margin-top: 20px;
background-color: #f8d7da;
color: #721c24;
padding: 10px;
border-radius: 5px;
}
/* 错误提示框 */
.form-text {
font-size: 12px;
color: #e3342f;
}
/* 密码强度提示样式 */
.password-strength {
font-size: 14px;
margin-top: 5px;
color: #28a745;
}
.password-strength.weak {
color: #dc3545;
}
.password-strength.medium {
color: #ffc107;
}
.password-strength.strong {
color: #28a745;
}
</style>
</head>
<body>
<div class="login-container">
<div class="login-card">
<h2 class="form-title">注册账户</h2>
<!-- 注册表单 -->
<form method="post">
{% csrf_token %}
<!-- 用户名输入框 -->
<div class="form-group">
<label for="id_username">用户名</label>
<input type="text" class="form-control {% if form.username.errors %}is-invalid{% endif %}"
id="id_username" name="username" value="{{ form.username.value }}" required autofocus>
{% if form.username.errors %}
<div class="form-text">
{% for error in form.username.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<!-- 密码输入框 -->
<div class="form-group">
<label for="id_password1">密码</label>
<input type="password" class="form-control {% if form.password1.errors %}is-invalid{% endif %}"
id="id_password1" name="password1" value="{{ form.password1.value }}" required>
<div id="password-strength" class="password-strength"></div>
{% if form.password1.errors %}
<div class="form-text">
{% for error in form.password1.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<!-- 密码确认输入框 -->
<div class="form-group">
<label for="id_password2">确认密码</label>
<input type="password" class="form-control {% if form.password2.errors %}is-invalid{% endif %}"
id="id_password2" name="password2" value="{{ form.password2.value }}" required>
{% if form.password2.errors %}
<div class="form-text">
{% for error in form.password2.errors %}
<p>{{ error }}</p>
{% endfor %}
</div>
{% endif %}
</div>
<button type="submit" class="btn btn-primary">注册</button>
</form>
<div class="text-muted mt-3">
已有账户? <a href="{% url 'login' %}">登录这里</a>
</div>
<!-- 显示系统级消息 -->
{% if messages %}
<div class="messages mt-3">
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
</div>
{% endif %}
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<script>
// 密码强度检测
const passwordInput = document.getElementById("id_password1");
const strengthOutput = document.getElementById("password-strength");
passwordInput.addEventListener("input", function () {
const password = passwordInput.value;
let strength = "weak";
if (password.length >= 8) {
const hasNumbers = /[0-9]/.test(password);
const hasLetters = /[a-zA-Z]/.test(password);
const hasSpecial = /[!@#$%^&*(),.?":{}|<>]/.test(password);
if (hasNumbers && hasLetters && hasSpecial) {
strength = "strong";
} else if (hasNumbers && hasLetters) {
strength = "medium";
}
}
strengthOutput.textContent = `密码强度: ${strength}`;
strengthOutput.className = `password-strength ${strength}`;
});
</script>
</body>
</html>
结论
通过以上步骤,实现了一个简单的用户登录系统,使用 Django 内置的认证视图、登录模板以及视图定制化来处理用户认证。
[下一篇,主页实现](Django login app 实现)