Django之Auth认证模块

news2024/11/30 1:27:23

文章目录

  • 一、简介
  • 二、Auth模块是什么
  • 三、Auth模块常用方法
    • create_user() 创建普通用户
    • authenticate() 用户认证
    • auth.login(HttpResponse,user)登录状态保持
    • is_authenticated 登录认证判断
    • auth.loginout(reqeust)退出登录
    • login_required() 登录认证装饰器
    • check_password(password) 检查密码
    • set_password(password)修改密码
    • 用户删除
    • 创建超级用户
  • 四、拓展Auth_user表

一、简介

在平常我们使用Django开发的过程中都需要设计Web用户系统其中包含:用户注册、登录、修改密码、登录认证、注销等功能。而这些都是由我们手动将数据拿到数据库表中一一匹对,太过于麻烦。那么我们今天使用到的Auth模块可以完美解决这个问题,提升使用Django的开发效率


二、Auth模块是什么

Auth是Django自带的用户认证模块

Django作为一个完美主义者的终极框架,当然也会想到开发者的这些痛点,它内置了强大的用户认证系统:auth,它默认使用auth_user表来存储用户数据(也就是第一次迁移数据库时Django创建的表之一)

三、Auth模块常用方法

auth模块常用的属性和方法:

属性或方法解释
auth.authenticate判断用户名和密码
is_authenticated判断用户是否登录
request.user获取当前登录用户
login_required校验用户是否登录装饰器
check_password校验密码是否正确
set_password修改密码
auth.logout(request)退出登录
create_user()创建用户和加密密码
AbstractUser基于auth扩写

我们可以通过一下来导入Auth模块:

	from django.contrib import auth

create_user() 创建普通用户

auth提供的一个创建新用户的方法,需要提供必要参数(username,password)等。

导入方式:

	from django.contrib.auth.models import User

我们创建的用户默认会被添加到auth_user表中,首先我们得有一个注册页面,便于能够快速起到效果,这里就没有校验二次密码了,有兴趣就自行添加即可。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1 class="text-center">注册页面</h1>
            <hr>
            <form action="" method="post">
                {% csrf_token %}
                <p>username:
                    <input type="text" name="username" class="form-control">
                </p>
                <p>password:
                    <input type="password" name="password" class="form-control">
                </p>
                <input type="submit" class="btn btn-block btn-success" value="注册">
            </form>
        </div>
    </div>
</div>
</body>
</html>

视图函数:

from django.contrib import auth
from django.contrib.auth.models import User
def register(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        # 校验用户名是否已存在
        # 这个方法必须要传递用户名和密码,单个不行会获取出None
        # obj = auth.authenticate(request,username=username,password=password)

        obj = User.objects.filter(username=username,password=password)
        if obj:
            return HttpResponse('用户名已存在')
        # 注册用户
        # User.objects.create(username=username,password=password) #不能自己创建,因为密码加密无法实现
        else:
            User.objects.create_user(username=username,password=password) # create_user方法会自动对密码加密
            return HttpResponse('注册成功!')


    return render(request,'register.html')

那么此时我们就实现了用户的账号注册功能。在auth_user表中就可以看到我们刚才注册的用户,并且Django帮助我们存储的过程中将密码进行了加密处理。

在这里插入图片描述


authenticate() 用户认证

提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username、password两个关键字参数。

导入方式:

	from django.contrib.auth import authenticate

如果认证成功(用户名和密码正确有效),便会返回一个User对象。

authenticate()会在该User对象上设置一个属性来标识后端已经认证了该用户,且该信息在后续的登录过程中是需要的。

登录Web

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1 class="text-center">登录页面</h1>
            <hr>
            <form action="" method="post">
                {% csrf_token %}
                <p>username:
                    <input type="text" name="username" class="form-control">
                </p>
                <p>password:
                    <input type="password" name="password" class="form-control">
                </p>
                <input type="submit" class="btn btn-block btn-success" value="登录">
            </form>
        </div>
    </div>
</div>
</body>
</html>

视图函数:

	def login(request):
	    if request.method == 'POST':
	        username = request.POST.get('username')
	        password = request.POST.get('password')
	
	        # 校验用户是否存在  自己是无法比对,因为密码存入其中加密了,所以需要用到auth模块提供的方法才可以
	        obj = auth.authenticate(request,username=username,password=password) # 用户名和密码正确之后返回的是数据对象,反之返回None
	        # print(obj.password, obj.username)
	
	        if obj:
	            return HttpResponse('登录成功!')
	        else:
	            return HttpResponse('用户名或密码错误!')
	
	    return render(request,'login.html')

此时,我们便已经完成验证用户账号和密码是否正确的一个功能,此时再浏览器输入正确的用户名与密码,就会显示登录成功!

究其本质还是Django把我们输入的内容拿到了auth_user表中对比,匹对成功了返回一个User对象给我们,只不过这些步骤我们只需要调用一个API就可以是实现。


auth.login(HttpResponse,user)登录状态保持

如果现在有一个home页面需要登录之后才能访问,那么我们就需要再用户登录之后制作一个登录标识保存在Session中,那么访问home页面校验一下Session即可判断出来。这是我们之前的操作,需要手动设置Session,在手动验证Session是否存在。

login函数接收一个HttpResponse对象,以及一个经过认证的User对象。

该函数实现一个用户登录的功能,它本质上会在后端为该用户生产相关session数据。

该函数需要再用户认证以后使用,因为它的第二个参数需要传入一个User对象。

	from django.contrib.auth import authenticate
	def login(request):
	    print(request.user.is_authenticated)  # True表示存在此用户,
	    print(request.user)  # 没有登录显示:AnonymousUser匿名用户    登录显示登录的用户对象数据
	    '''
        用户登录成功之后执行Auth.login 该方法返回当前登录用户对象  admin
        用户没有登录成功没有执行Auth.login 该方法返回匿名用户对象  AnonymousUser
		'''
		
	    if request.method == 'POST':
	        username = request.POST.get('username')
	        password = request.POST.get('password')
	
	        # 校验用户是否存在  自己是无法比对,因为密码存入其中加密了,所以需要用到auth模块提供的方法才可以
	        obj = auth.authenticate(request,username=username,password=password) # 用户名和密码正确之后返回的是数据对象,反之返回None
	        print(obj.password, obj.username)
	
	        if obj:
	            # 用户登录成功后(返回给客户端一个登录凭证、字符串、令牌)
	            auth.login(request, obj)  # 自动操作django_session表,返回一个凭证给客户端
	            '''
	            当执行上述的操作之后,我们就可以通过reqeust.user直接获取到当前登录的用户对象数据
	            '''
	            return HttpResponse('登录成功!')
	        else:
	            return HttpResponse('用户名或密码错误!')
	
	    return render(request,'login.html')

此时我们还需配合下面的Auth方法一起使用才能看到效果


is_authenticated 登录认证判断

用来判断当前请求是否通过了登录认证。其主要还是判断请求内是否包含用户登录后的Session

定义一个home页面,只有检测到用户登录后才能访问,否则重定向到登录页面

登录验证Web

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
{% if request.user.is_authenticated %}  # 判断当前请求是否为登录状态
	<h1>{{ request.user.username}}</h1>
{% else %}
    <a href="/auth_register/">注册</a>
    <a href="/auth_login/">登录</a>
{% endif %} 
</body>
</html>

视图函数:

	def home(request):
    	return render(request,'home.html')

ps:reqeust.use具备很多方法,一些其它的常用方法在有需求的情况下在做了解

reqeust.user.username :查看当前登录的用户名
request.user.password :查看当前登录的用户密码(加密形式的)

到这里我们已经实现了登录认证,登录状态保持的一个效果,后端也可以识别当前是否为登录状态,并且知道当前登录的用户是那个。


auth.loginout(reqeust)退出登录

该函数接受一个HttpResponse对象,无返回值。

当调用该函数时,当前请求的Session信息会被全部清除。即使没有登录,使用该函数也不会报错。

后端清空了当前用户保存的Session信息,也可以理解为没有登录状态了,下次访问某些页面需要重新登录

	def login_out(request):
	    auth.logout(request)
	    return HttpResponse('已注销用户!')

当是这种退出登录,不管什么登录状态的都清除掉session这样不算合格,所以我们需要先校验是否登录。


login_required() 登录认证装饰器

在上面我们是通过Web页面里面使用了request.user.is_authenticated校验是否登录的

现在我们为了更加简单实现,auth给我们提供了一个装饰器工具,用来快捷的给某个视图添加登录校验

	@login_required
	def login_out(request):
	    auth.logout(request)
	    return HttpResponse('已注销用户!')

若用户没有登录,则会跳转到Django默认的登录URL/accounts/login/并且URL会额外显示:?next=/跳转之前的路径/

如果需要自定义登录的URL,有两种方式:

  1. 需要再settings.py文件中通过LOGIN_URL进行修改。
	LOGIN_URL = '/auth_login/' #这里配置成你的项目登录页面的路由
  1. 手动指定:用户没有登录时重定向到登录页面
	@login_required(login_url='/auth_login/')
	def indexs(request):
	    # if request.user.is_authenticated:
	    #     return HttpResponse('只有登录的用户可见')
	    # else:
	    #     return redirect('/auth_login/')
	    return HttpResponse('只有登录的用户可见')

如果我们想要在登录之后立马跳转到被重定向之前的页面,使用方式一,因为它会保留定义之前的URL:

	 if obj:
		# 用户登录成功后(返回给客户端一个登录凭证、字符串、令牌)
		auth.login(request, obj)  # 自动操作django_session表,返回一个凭证给客户端
		urls = reqeust.GET.get('next')
		if not urls:
			urls = '/index/'  # 如果没有获取到,就默认登录后跳转到首页
		return redirect(urls)

check_password(password) 检查密码

auth提供的一个检查密码是否正确的方法,需要提供当前请求用户的密码。

密码正确返回True,否则返回False。但必须在登录之后并且保存了登录Session才能使用

使用方法:

	user = request.user.check_password('密码')

set_password(password)修改密码

auth 提供的一个修改密码的方法,接受要设置的新密码作为参数。

注意:设置完一定要调用用户对象的save方法!!! 通常在check_password校验之后使用

我们使用这两个来实现修改密码的功能

web:set_html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <h1 class="text-center">修改密码页面</h1>
            <hr>
            <form action="" method="post">
                {% csrf_token %}
                <p>username:
                    <input type="text" name="username" class="form-control" value="{{ request.user.username }}" disabled>
                </p>
                <p>oldpassword:
                    <input type="password" name="old_pwd" class="form-control">
                </p>
                <p>newpassword:
                    <input type="password" name="new_pwd" class="form-control">
                </p>
                <p>Confirm_password
                    <input type="password" name="confirm_pwd" class="form-control">
                </p>
                <input type="submit" class="btn btn-block btn-success" value="提交">
            </form>
        </div>
    </div>
</div>
</body>
</html>

视图函数:

@login_required
def set_pwd(request):
    if request.method == 'POST':
    	user = request.user # 获取当前用户对象
        old_pwd = request.POST.get('old_pwd')  # 获取用户输入的旧密码
        new_pwd = request.POST.get('new_pwd')  # 获取用户输入的新密码
        confirm_pwd = request.POST.get('confirm_pwd')  # 二次确认新密码

        if not new_pwd == confirm_pwd:
            return HttpResponse('两次密码不一致')
            
        # 判断原密码是否正确
        res = request.user.check_password(old_pwd)
        if not res:
            return HttpResponse('原密码错误!')
        else:
            #修改密码
            request.user.set_password(new_pwd)
            request.user.save()  # 将修改后的数据保存在auth_user表中

			auth.login(request,user) # 因为用户信息发生变动,需要修改用户的session数据才能保持登录状态
            return HttpResponse('修改成功!')

    return render(request,'set.html')

用户删除

如果是管理员的话,可以删除其他用户,如果是普通用户的话,只能删除自己

管理员删除需要前端传递一个用户id到后端才能进行删除;需要路由定义分组来接收并传递给视图函数

	# 管理员删除用户
	@login_required
	def auth_delete(request,id):
	    auth.logout(request)
	    user = User.objects.filter(pk=id)
	    user.delete()
	    return HttpResponse('.....')

	路由层配置urls.py
	re_path('auth_delete/(\dt)/', views.auth_delete,name='auth_delete'),

普通用户,仅只能删除自身

	@login_required
	def auth_delete(request):
		request.user.delete()
		return HttpResponse('.....')

注意:如果连接的是sqlite数据库,很可能会删除失效,建议换成MySQL数据库


创建超级用户

超级用户首先具备登录admin后端的能力,其次可以在里面删除其它用户;

超级用户的创建方式有两种:

  1. 通过:Python3 manage.py createsuperuser命令,根据提示输入用户名、邮箱(可输入空)、密码、二次密码等
  2. 通过Auth组件创建;与创建普通用户区别不大,只是获得权限不同

第一种方式:

django自带一个admin路由,但是需要我们提供管理员账户和密码,如果想要使用admin后台管理,需要先创建表,然后创建管理员账户。

在这里插入图片描述
直接执行数据类迁移命令即可产生默认的auth_user表,该表就是admin后台管理默认的认证表
在这里插入图片描述

​ 在控制台输入命令python38 manage.py createsuperuser

在执行创建管理员命令后,运行环境会提示我们输入用户名,邮箱(选填),密码等信息,依次输入即可。这样我们的auth_user表中就会添加一条数据,这条数据就是管理员用户信息。


第二种方式:
web:super_register.html 建立超级用户

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container">
    <div class="row">
        <h1 class="text-center">超级用户创建</h1>
        <form action="" method="post">
            {% csrf_token %}
            <p>用户名:<input type="text" name="username" class="form-control"></p>
            <p>邮箱:<input type="email" name="email" class="form-control"></p>
            <p>密码:<input type="password" name="password" class="form-control"></p>
            <p><input type="submit" value="提交" class="form-control btn-warning"></p>
        </form>
    </div>
</div>
</body>
</html>

视图函数

	# 创建超级管理员用户
	def auth_super_register(request):
	    if request.method == 'POST':
	        username = request.POST.get('username')
	        email =request.POST.get('email')
	        password = request.POST.get('password')
	
	        User.objects.create_superuser(username=username,email=email,password=password)
	        return HttpResponse('超级用户创建成功!')
	
	    return render(request,'super_register.html')

创建完成以后我们就可以通过刚刚创建的账号和密码登录到Django的admin后台管理界面了

在这里插入图片描述


四、拓展Auth_user表

在原来的基础authmok的功能,并且又想扩展auth_user表的字段

思路1:一对一字段关联(不推荐)

	from django.contrib.auth.models import User
	class OtherUser(models.Model):
	    user = models.OneToOneField(to=User)
	    """ 将User表与OtherUser的字段一一对应,操作起来很麻烦"""

思路2:替换auth_user表(推荐)

	步骤1:模型层编写模型类继承AbstractUser
	from django.contrib.auth.models import AbstractUser
    class UserInfo(AbstactUser):  # 继承原管理表格
        # 填写AbstactUser表中没有的字段
        phone=models.BinIntegerField()  # 可以随意添加
        desc=models.TextField()
        
	步骤2:一定要配置文件中声明替换关系
		AUTH_USER_MODEL='app01.UserInfo'
	    # 告诉orm 使用app01 下的UserInfo表替换原先的auth_user表
	    ps:替换还有一个前提,就是数据库迁移命令没有执行过(auth相关表没有创建),用全新的库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1256086.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

枚举的第一行

2023年11月26日 问题: 好奇enum的所声明的枚举类的第一行是什么 从java技术卷1中第五章5.6中,了解是枚举类的实例 验证 错误信息: 解释: 此时只有有参构造 在这个枚举类里不能使用空,大概意思是说不能使用空参创建实例 校验 在原有的基础上创建一个无参构造 结果:不再报错,第…

Adversarial Attack on Graph Structured Data(2018 PMLR)

Adversarial Attack on Graph Structured Data----《图结构数据的对抗攻击》 摘要 基于图结构的深度学习已经在各种应用中显示出令人兴奋的结果。然而&#xff0c;与图像或文本对抗攻击和防御的大量研究工作相比&#xff0c;此类模型的鲁棒性却很少受到关注。在本文中&#xf…

【数据中台】开源项目(2)-Moonbox计算服务平台

Moonbox是一个DVtaaS&#xff08;Data Virtualization as a Service&#xff09;平台解决方案。 Moonbox基于数据虚拟化设计思想&#xff0c;致力于提供批量计算服务解决方案。Moonbox负责屏蔽底层数据源的物理和使用细节&#xff0c;为用户带来虚拟数据库般使用体验&#xff0…

Python 进阶(十):数学计算(math 模块)

《Python入门核心技术》专栏总目录・点这里 文章目录 1. 导入math模块2. 常用数学函数3. 常量4. 其他函数和用法5. 总结 大家好&#xff0c;我是水滴~~ Python的math模块提供了许多数学运算函数&#xff0c;为开发者在数值计算和数据处理方面提供了强大的工具。本教程将详细介…

【python】Python将100个PDF文件对应的json文件存储到MySql数据库(源码)【独一无二】

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

[AutoSAR存储] 车载存储层次 和 常用存储芯片概述

公知及经验整理&#xff0c;原创保护&#xff0c;禁止转载。 专栏 《AutoSAR存储》 <<<< 返回总目录 <<<< 1 存储系统层次 先抛个问题&#xff0c; 为什么要划分存储器的层次&#xff1f; 速度越快&#xff0c;但成本越高&#xff0c;从经济的角度规…

基本数据结构二叉树(1)

目录 1.树概念及结构 1.1树的概念 1.2 树的相关概念 1.3 树的表示 1.4 树在实际中的运用&#xff08;表示文件系统的目录树结构&#xff09; 2.二叉树概念及结构 2.1概念 2.2现实中的二叉树&#xff1a; 2.3 特殊的二叉树&#xff1a; 2.5 二叉树的存储结构 2. 链式存…

leetcode面试经典150题——32 串联所有单词的子串(中等+困难)

题目&#xff1a; 串联所有单词的子串(1中等) 描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找到 s 中所有 p 的 异位词 的子串&#xff0c;返回这些子串的起始索引。不考虑答案输出的顺序。 异位词 指由相同字母重排列形成的字符串&#xff08;包括相同的字符串&…

MySQL基本SQL语句(上)

MySQL基本SQL语句&#xff08;上&#xff09; 一、客户端工具的使用 1、客户端工具mysql使用 mysql: mysql命令行工具&#xff0c;一般用来连接访问mysql数据库 选项说明-u, --username指定登录用户名-p, --password指定登录密码(注意是小写p),一定要放到最后面-h, --hostn…

【Spring】Spring事务失效问题

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;2022年度博客之星全国TOP3&#xff0c;专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化&#xff0c;文章内容兼具广度、深度、大厂技术方案&#xff0c;对待技术喜欢推理加验证&#xff0c;就职于…

我的第一次SACC之旅

今年有很多第一次&#xff0c;第一次作为“游客”参加DTCC&#xff08;中国数据库大会&#xff09;&#xff0c;第一次作为讲师参与ACDU中国行&#xff08;成都站&#xff09;&#xff0c;第一次参加OB年度发布会&#xff08;包含DBA老友会&#xff09;&#xff0c;而这次是第一…

Android获取原始图片Bitmap的宽高大小尺寸,Kotlin

Android获取原始图片Bitmap的宽高大小尺寸&#xff0c;Kotlin val options BitmapFactory.Options()options.inJustDecodeBounds trueval decodeBmp BitmapFactory.decodeResource(resources, R.mipmap.p1, options)//此时&#xff0c;decode出来的decodeBmp宽高并不是原始图…

NX二次开发UF_CURVE_ask_spline_feature 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CURVE_ask_spline_feature Defined in: uf_curve.h int UF_CURVE_ask_spline_feature(tag_t feature_id, tag_t * spline ) overview 概述 Inquire a general spline feature. …

如何深刻理解从二项式分布到泊松分布

泊松镇贴 二项分布和泊松分布的表达式 二项分布&#xff1a; P ( x k ) C n k p k ( 1 − p ) n − k P(xk) C_n^kp^k(1-p)^{n-k} P(xk)Cnk​pk(1−p)n−k 泊松分布&#xff1a; P ( x k ) λ k k ! e − λ P(xk) \frac{\lambda^k}{k!}e^{-\lambda} P(xk)k!λk​e−…

18. Python 数据处理之 Numpy

目录 1. 简介2. 安装和导入Numpy3. ndarray 对象4. 基本运算5. 索引、切片和迭代6. 条件和布尔数组7. 变换形状8. 操作数组 1. 简介 数据分析的流程概括起来主要是&#xff1a;读写、处理计算、分析建模和可视化4个部分。 Numpy 是Python 进行科学计算&#xff0c;数据分析时…

【咕咕送书 | 第六期】深入浅出阐述嵌入式虚拟机原理,实现“小而能”嵌入式虚拟机!

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《粉丝福利》 《linux深造日志》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 ⛳️ 写在前面参与规则引言一、为什么嵌入式系统需要虚拟化技术&#xff1f;1.1 专家推荐 二、本书适合谁&#x…

【Vue】@keyup.enter @v-model.trim的用法

目录 keyup.enter v-model.trim 情景一&#xff1a; 情景二&#xff1a; keyup.enter 作用&#xff1a;监听键盘回车事件 上一篇内容&#xff1a; 记事本 https://blog.csdn.net/m0_67930426/article/details/134630834?spm1001.2014.3001.5502 这里有个添加任务的功能&…

ESP32控制数码管实现数字叠加案例

经过了几个小时的接线和代码实现终于搞定了代码&#xff0c;贴出来大家参考下 import machine import time# 定义4个Led的引脚 led1 machine.Pin(5,machine.Pin.OUT) led2 machine.Pin(18,machine.Pin.OUT) led3 machine.Pin(19,machine.Pin.OUT) led4 machine.Pin(21,mac…

i社为什么不出游戏了?

I社&#xff0c;即国际知名的游戏公司&#xff0c;近来为何鲜有新游问世&#xff1f;曾经风靡一时的游戏开发者&#xff0c;如今为何陷入了沉寂&#xff1f;这其中的种种原因&#xff0c;值得我们深入剖析。 首先&#xff0c;I社近期的沉寂可能与其内部管理层的调整和战略规划…

VUE简易购物车程序

目录 效果预览图 完整代码 效果预览图 完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>…