1.设计用户模型
文件地址:accounts/models.py
1.1 用户详细信息
内容包括:性别 手机号 年龄 生日 真实姓名
创建常量:1-男,0-女;editable=False不许循环
class Profile(models.Model):SEX_CHOICES={(1,'男'),(0,'女')}username = models.CharField('用户名',max_length=64, unique=True,editable=False)user = models.OneToOneField(User,related_name="profile",on_delete=models.CASCADE)real_name = models.CharField('真实姓名',max_length=32)email = models.CharField('电子邮件',max_length=128,null=True,blank=True)is_email_valid = models.BooleanField('电子邮件是否已经被验证',default=False)phone_no = models.CharField('手机号码',max_length=20,null=True,blank=True)is_phone_valid = models.BooleanField('电话号码是否已经被验证', default=False)sex = models.SmallIntegerField('性别',default=1,choices=SEX_CHOICES)age = models.SmallIntegerField('年龄', default=0)source = models.CharField('登录的来源',max_length=16,null=True)version = models.CharField('登录的版本',max_length=32,null=True)created_at = models.DateTimeField('登录时间',auto_now_add=True)updated_at = models.DateTimeField('修改时间',auto_now=True)class Meta:db_table = "accounts_user_profile"
1.2 用户登录日志
class LoginRecord(models.Model):user = models.ForeignKey(User,related_name='login_records',on_delete=models.CASCADE)username = models.CharField('登录的账号',max_length=64)ip = models.CharField('IP',max_length=32)address = models.CharField('地址',max_length=32,null=True,blank=True)source = models.CharField('登录的来源',max_length=16,null=True)version = models.CharField('登录的版本', max_length=16, null=True)created_at = models.DateTimeField('登录的时间',auto_now_add=True)class Meta:db_table = "accounts_login_record"
2.数据迁移
python manage.py check
python manage.py makemigrations
python manage.py migrate
3.准备Django模板
3.1 创建用户模板文件
3.2 用户登录
文件地址:accounts/templates/user_login.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>用户登录</title>
</head>
<body><h3>用户登录</h3><form method="post" action="."><div><!--用户名-->{{ form.username.label }}<!--用户名文字提示-->{{ form.username }}<!--用户名文本-->{{ form.username.errors.as_text }}<!--用户名错误--></div><div><!--密码-->{{ form.password.label }}<!--密码文字提示-->{{ form.password }}<!--密码文本-->{{ form.password.errors.as_text }}<!--密码错误--></div><div>{{ form.non_field_errors.as_text }} <!--验证错误提示--></div><input type="submit" value="登录"></form>
</body>
</html>
3.3 用户基本信息
文件地址:accounts/templates/user_info.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>用户的基本信息</title>
</head>
<body><p>当前登录的用户是:{{ user.username }}-{{ user.email }}</p>{% if user.is_authenticated %}<a href="/accounts/user/logout">退出登录</a>{% endif %}
</body>
</html>
3.4 配置setting
import os
MIDDLEWARE = ['django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware',# 'django.middleware.csrf.CsrfViewMiddleware',👈把它删咯'django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [os.path.join(BASE_DIR / 'templates')],👈加上os.path.join'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',],},},
]
4.表单验证
新建文件:accounts/forms.py
继承父类 重写子类
import re
from django import forms
from django.contrib.auth import authenticate, login
from django.utils.timezone import nowclass LoginForm(forms.Form):# 登录表单username = forms.CharField(label='用户名',max_length=100,required=False,help_text='使用帮助',initial='admin')password = forms.CharField(label='密码',max_length=200,min_length=6,widget=forms.PasswordInput)#初始化函数,将传入的数据给到父类中处理def __init__(self,*args,**kwargs):super().__init__(*args,**kwargs)self.user = None#验证用户名的钩子函数def clean_username(self):username = self.cleaned_data['username']pattern = r'^1[0-9]{10}$'if not re.search(pattern,username):raise forms.ValidationError('手机号%s输入不正确',code='invalid_phone',params=(username,))return username#用户名密码验证def clean(self):data = super().clean()if self.errors:return#获取模板中输入的用户名密码username = data.get('username',None)password = data.get('password',None)#验证用户名密码是否正确user = authenticate(username=username,password=password)if user is None:raise forms.ValidationError('用户名或密码不正确')else:if not user.is_active:raise forms.ValidationError('该用户已经被禁用')self.user = userreturn data#登陆函数def do_login(self,request):user = self.user#调用登录login(request, user)#修改登陆时间user.last_login = now()user.save()return user
5.用户登录视图函数
from django.contrib.auth import logout
from django.shortcuts import render, redirect
from accounts.forms import LoginForm
def user_login(request):#用户登录if request.method == 'POST':form = LoginForm(data=request.POST)if form.is_valid():form.do_login(request)print('表单验证通过')return redirect('/accounts/user/info/')else:print(form.errors)else:form = LoginForm()return render(request,'user_login.html',{'form':form})def user_info(request):#用户信息print(request.user)return render(request, 'user_info.html')def user_logout(request):#退出登录logout(request)return redirect('/accounts/user/info/')
6.配置路由
新建文件:accounts/urls.py
from django.urls import path
from accounts import viewsurlpatterns = [#用户登录path('user/login/',views.user_login,name='user_login'),#用户详细信息path('user/info/',views.user_info,name='user_info'),#用户退出登录path('user/logout/',views.user_logout,name='user_logout')
]
全局urls: