当前位置: 首页 > article >正文

Vue全栈开发旅游网项目(10)-设计用户模型

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 now

class 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 = user
        return 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 views

urlpatterns = [
    #用户登录
    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:

7.登录结果


http://www.kler.cn/a/390964.html

相关文章:

  • ❤React-React 组件通讯
  • Web安全之SQL注入---基础
  • 低代码集成多方API的简单实现
  • ODOO学习笔记(1):ODOO的SWOT分析和技术优势是什么?
  • 羊城杯2020Easyphp
  • 线性表-数组描述补充 迭代器(C++)
  • C++ | Leetcode C++题解之第557题反转字符串中的单词III
  • Rust使用DX11进行截图并保存
  • 逻辑的空无
  • SQL的三值逻辑
  • 基于vue框架的的汽车租赁系统34311(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • HTML查缺补漏
  • playwright学习记录2--定位方式
  • 【Unity/GameFramework】Start Force ——配置和表加载
  • 二分答案-整型二分—愤怒的牛-P1676 [USACO05FEB] Aggressive cows G
  • 微服务架构面试内容整理-监控与追踪-Zipkin
  • AlphaFold3中文安装教程
  • Unity类银河战士恶魔城学习总结(P117 Ice And Fire Item Effec 制作一把冰火属性的剑)
  • 练习题 - Django 4.x WWW 网址使用示例和配置方法
  • Git推送报错Authentication failed
  • 深入探讨钉钉与金蝶云星空的数据集成技术
  • 在linux上搭建一个nodejs服务_全流程
  • 如何将交叉编译配置在环境变量中
  • arcgis for js实现popupTemplate弹窗field名称和值转义
  • 【MySQL 保姆级教学】事务的自动提交和手动提交(重点)--上(13)
  • 【开源免费】基于SpringBoot+Vue.JS宠物咖啡馆平台(JAVA毕业设计)