先配置数据库settings中
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django_user',
'USER': 'root',
'PASSWORD': '123456',
'HOST': 'localhost',
'PORT': 3306
}
}
app urls
# coding:utf-8
from django.urls import path
from .views import Regist
urlpatterns = [
path('regist', Regist.as_view(), name='regist')
]
views
# coding:utf-8
from django.shortcuts import render
from django.views.generic import View
class Regist(View):
TEMPLATE = 'regist.html'
def get(self, request):
return render(request, self.TEMPLATE)
templates中的regist(记得注册templates)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
</head>
<body>
<form>
<input type="text" placeholder="请输入用户名">
<input type="password" placeholder="请输入密码">
<input type="password" placeholder="确认密码">
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
</html>
启动后
display:
block:每个input占据一行
inline:input默认是inline
inline-block:把一个行级元素内容有了一个块级元素
下图为block效果
margin-left: 50% 距离左边有50%的间距。
float:right 到最右边(不过层级会改变)
margin-top: 50px:距离最上面50像素。
csrf是一种保护机制,是为了防止一种跨站的恶意攻击,才出现的一种加密的访问。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册</title>
<style>
#edit-area{
width: 25%;
margin: 0 auto;
margin-top: 50px;
}
input{
display: block;
width: 100%;
}
#submit, #reset{
width: 40px;
display: inline-block;
}
#reset{
float: right;
}
</style>
</head>
<body>
<form id="edit-area" action="{% url 'regist' %}" method="post">
{% csrf_token %}
<input type="text" placeholder="请输入用户名">
<input type="password" placeholder="请输入密码">
<input type="password" placeholder="确认密码">
<input id="submit" type="submit" value="提交">
<input id="reset" type="reset" value="重置">
</form>
</body>
</html>
把前端数据和后端关联:
加上name
<input name="username" type="text" placeholder="请输入用户名">
<input name="password" type="password" placeholder="请输入密码">
<input name="check_password" type="password" placeholder="确认密码">
<input id="submit" type="submit" value="提交">
<input id="reset" type="reset" value="重置">
然后后端拿到表单post的内容。views中加上post
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
check_password = request.POST.get('check_password')
print(username, password, check_password)
return redirect('/regist')
收到了,
注册
接下来对数据进行一个注册。views中
class Regist(View):
TEMPLATE = 'regist.html'
def get(self, request):
error = request.GET.get('error', '') # 拿到post中 密码输入不同后error的值 然后在前端显示出来
return render(request, self.TEMPLATE, {'error': error})
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
check_password = request.POST.get('check_password')
if password != check_password:
return redirect('/regist?error=密码不同')
print(username, password, check_password)
return redirect('/regist')
# coding:utf-8
from django.contrib.auth.models import User
from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from django.contrib.auth.hashers import make_password # 加密工具
class Regist(View):
TEMPLATE = 'regist.html'
def get(self, request):
error = request.GET.get('error', '') # 拿到post中 密码输入不同后error的值 然后在前端显示出来
return render(request, self.TEMPLATE, {'error': error})
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
check_password = request.POST.get('check_password')
if password != check_password:
return redirect('/regist?error=密码不同')
# 验证一下username是否已经注册了
exists = User.objects.filter(username=username).exists()
if exists: # 如果是1 就是已经注册了
return redirect('/regist?error=该用户名已存在')
hash_password = make_password(password) # 如果密码前后一致,就哈希加密一下
user = User.objects.create_user(username=username, password=hash_password)
user.save()
return redirect(reverse('login'))
class Login(View):
TEMPLATE = 'login.html'
def get(self, request):
return render(request, self.TEMPLATE)
注册成功了,会跳转到login页面
先更新一下数据库,然后在页面注册一下:
然后在数据库中能看到注册的用户,密码被加密了,不是staff也不是超级管理员。
现在注册就完成了,接下来是登录。
登录
login页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
<style>
form {
width: 20%;
margin: 0 auto;
margin-top: 100px;
padding: 2%;
border: 1px solid #cccccc;
border-radius: 8px;
}
</style>
</head>
<body>
<form>
<input type="text" name="username" placeholder="用户名" required>
<input type="password" name="password" placeholder="密码" required>
<input type="submit" value="登录">
</form>
</body>
#cccccc一种灰色
padding 简写属性在一个声明中设置所有内边距属性。
说明
这个简写属性设置元素所有内边距的宽度,或者设置各边上内边距的宽度。行内非替换元素上设置的内边距不会影响行高计算;因此,如果一个元素既有内边距又有背景,从视觉上看可能会延伸到其他行,有可能还会与其他内容重叠。元素的背景会延伸穿过内边距。不允许指定负边距值。
例子 1
padding:10px 5px 15px 20px;
上内边距是 10px
右内边距是 5px
下内边距是 15px
左内边距是 20px
border-radius:添加圆角
完整views
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>login</title>
<style>
form {
width: 20%;
margin: 0 auto;
margin-top: 100px;
padding: 2%;
border: 1px solid #cccccc;
border-radius: 8px;
}
input {
display: block;
width: 100%;
}
#submit{
width: 40px;
}
</style>
</head>
<body>
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
<input type="text" name="username" placeholder="用户名" required>
<input type="password" name="password" placeholder="密码" required>
<input id="submit" type="submit" value="登录">
</form>
</body>
然后后端要对post接收一下:
from django.contrib.auth import login, logout, authenticate # 登录验证 和登出 验证
class Login(View):
TEMPLATE = 'login.html'
def get(self, request):
return render(request, self.TEMPLATE)
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
# 拿到username 和 password之后要先对其进行验证
user = authenticate(username=username, password=password)
if user: # 如果用户存在
print('login success! ', user)
else:
print('login fail ~ ', user)
return redirect(reverse('login')) # 这里的login前面不要加 /
先检验一下效果:
错误时:
这里尝试了一下正确输入,结果依旧是fail。
推断可能是注册部分:
# hash_password = make_password(password) # 如果密码前后一致,就哈希加密一下
user = User.objects.create_user(username=username, password=password)
这里用的是create_user,会自动将我们的password加入然后存入,就不需要手动再hash了。
如果是用create的话,就需要手动hash。
于是我们把之前的user删掉再重新注册一下:
看到上面确实是自动加密的了。
然后我们这里也显示success
接下来写登入
def get(self, request):
error = request.GET.get('error')
return render(request, self.TEMPLATE, {'error':error})
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
# 拿到username 和 password之后要先对其进行验证
user = authenticate(username=username, password=password)
if user: # 如果用户存在
login(request, user) # 登录
else:
return redirect('/login?error=登录失败') # 登录错误就传一个error,get里面获取error的值
return redirect(reverse('login')) # 这里的login前面不要加 /
区分用户名错误和密码错误
def post(self, request):
username = request.POST.get('username')
password = request.POST.get('password')
exists = User.objects.filter(username=username).exists()
# 先验证用户名是否存在
if not exists: # 如果用户名不存在
return redirect('/login?error=没有该用户')
# 上面验证完用户名,接下来就验证password
user = authenticate(username=username, password=password)
if user: # 如果password正确
login(request, user) # 登录
else:
return redirect('/login?error=密码错误') # 登录错误就传一个error,get里面获取error的值
return redirect(reverse('login')) # 这里的login前面不要加 /
登出:
class LogoutUser(View):
def get(self, request):
logout(request)
return redirect(reverse('login')) # 退出登录就让他再回到登录页面
urls也配置一下:
urlpatterns = [
path('regist', Regist.as_view(), name='regist'),
path('login', Login.as_view(), name='login'),
path('logout', LogoutUser.as_view(), name='logout')
]
接下来确认是否成功登录:
class Regist(View):
TEMPLATE = 'regist.html'
def get(self, request):
if request.user.is_authenticated:
return redirect(reverse('login'))
因为我们的login页面无法logout,所以我们再增加一个logout按钮。
<body>
{% if not user.is_authenticated %}
<form action="{% url 'login' %}" method="post">
{% csrf_token %}
<input type="text" name="username" placeholder="用户名" required>
<input type="password" name="password" placeholder="密码" required>
<input id="submit" type="submit" value="登录">
{{error}}
</form>
{% else %}
<a href="{% url 'logout' %}">退出登录</a>
{% endif %}
</body>
然后我们现在再创建一个superuser
进入admin看一下
状态不同。