Django入门教程——用户管理实现

第六章 用户管理实现

教学目的

  • 复习数据的增删改查的实现。
  • 了解数据MD5加密算法以及实现
  • 模型表单中,自定义控件的使用
  • 中间件的原理和使用

需求分析

系统问题

  • 员工档案涉及到员工的秘密,不能让任何人都可以看到,主要是人事部门进行数据的维护,公司领导具有数据的查看权限。
  • 现在我们开发出来的功能,所有人都可以进行访问,都可以进行数据的修改,不符合需求。

系统功能

  • 管理员用户可以进行用户管理,实现用户的添加、修改、删除等
  • 普通用户可以登录系统,修改个人密码等

用户管理相关数据模型

数据模型设计

在这里插入图片描述

添加用户管理相关数据模型

  1. 添加新的应用python manage.py startapp userinfo

  2. 注册新的应用

    INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','archives','userinfo',
    ]
    
  3. 创建数据模型

    # 用户信息
    class User(models.Model):username = models.CharField(verbose_name='用户账号', max_length=30)password = models.CharField(verbose_name='用户密码', max_length=40)employee = models.ForeignKey(to="archives.Employee", on_delete=models.CASCADE, verbose_name='员工ID', null=True)avatarUrl = models.CharField(verbose_name="头像", max_length=250, null=True, blank=True)role = models.ForeignKey(to="Role", to_field="id", on_delete=models.SET_NULL, verbose_name='角色', null=True)last_login = models.DateTimeField(verbose_name='最后登录时间', auto_now=True)create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)class Meta:db_table = 'sys_user'# 角色
    class Role(models.Model):name = models.CharField(verbose_name='角色名称', max_length=50)remark = models.CharField(verbose_name='备注', max_length=255, null=True, blank=True, )class Meta:db_table = 'sys_role'def __str__(self):return self.name
    
  4. 执行命令创建数据表

    python manage.py makemigrations          
    python manage.py migrate
    

用户的增删改查

  1. 用户列表页面user_list.html

    {%extends 'common/base_list.html'%}
    {% block templet %}
    <!-- 顶部工具栏模板 -->
    <script type="text/html" id="toolbar"><div class="layui-btn-container"><button class="layui-btn  layui-btn-sm" lay-event="add"><i class="layui-icon layui-icon-addition"></i>新增</button></div>
    </script>
    <!-- 表格操作模板 -->
    <script type="text/html" id="TableBar"><div class="layui-clear-space"><a class="layui-btn layui-btn-xs " lay-event="edit"><i class="layui-icon layui-icon-edit"></i>编辑</a><a class="layui-btn layui-btn-xs layui-bg-red" lay-event="delete"><i class="layui-icon layui-icon-delete"></i>删除</a></div>
    </script>
    {%endblock%}
    {% block js %}
    <script>
    layui.use(function(){var $ = layui.jquery,form = layui.form,table = layui.table,layer = layui.layer;// 渲染表格table.render({elem: '#TableId',url: '/user/list/',method:'post',toolbar: '#toolbar',defaultToolbar: ['filter', 'exports', 'print'],cols: [[{type: "checkbox", width: 50},{field: 'index', width: 80, title: '序号',align:'center', sort: true},{field: 'id', width: 80, title: 'ID',align:'center', sort: true,hide:true},{field: 'username', width: 150, title: '用户名',align:'center',sort: true},{field: 'employee', width: 150, title: '姓名',align:'center',sort: true},{field: 'role', width: 150, title: '角色',align:'center',sort: true},{field: 'last_login', width: 150, title: '最近登录',align:'center',sort: true},{title: '操作', minWidth: 240, toolbar: '#TableBar', align: "center", fixed: 'right' }]],limits: [10, 20, 50,100,200,500],limit: 10,page: true,skin: 'row',even: true,});// 头部工具栏事件table.on('toolbar(TableFilter)', function (obj) {if (obj.event === 'add') {layer.open({title: ['新增', 'font-size:18px;font-weight:bold;'],type: 2,shade: 0.3,maxmin:true,shadeClose: true,area: ['60%', '600px'],content: '/user/add/',});}});
    });
    </script>
    {%endblock%}
    
  2. 建立视图函数

    # 用户列表
    @csrf_exempt
    def user_list(request):if request.method == "GET":return render(request,"userinfo/user_list.html")page = request.POST.get('page', 1)limit = request.POST.get('limit', 10)searchParams = request.POST.get('searchParams', None)data_obj = User.objects.all()data_page = Paginator(data_obj, limit).page(page)data_list=[]count = (int(page) - 1) * int(limit)for row in data_page:count += 1item_dict = {}field_names = [field.name for field in row._meta.fields]for field in field_names:if field == "employee":item_dict[field] = row.employee.nameelif field == "role":item_dict[field] = row.role.nameelse:item_dict[field] = getattr(row,field)item_dict["index"]=countdata_list.append(item_dict)return res_json_data.table_api(data=data_list,count=len(data_obj))
    
  3. 建立url路由

    from userinfo import views as user_views
    path("user/list/",user_views.user_list),
    
  4. 建立用户编辑表单类

    class edit_form(forms.ModelForm):class Meta:model = models.Userfields = ['username','role','employee']widgets = {"employee":forms.Select(attrs={"lay-search":""}),}def __init__(self,*args,**kwargs):super().__init__(*args,**kwargs)for name,field in self.fields.items():field.widget.attrs.update({"class":"layui-input","placeholder":"输入"+field.label})
    
  5. 建立添加视图函数

    #settings.py
    DEFAULT_PASSWORD = '123'  # 设置默认密码
    
    from django.conf import settings
    # 用户添加
    def user_add(request):if request.method == "GET":form = user_form.edit_form()return render(request,"userinfo/user_edit.html",{"form":form})form = user_form.edit_form(data=request.POST)if form.is_valid():form.instance.password = settings.DEFAULT_PASSWORDform.save()messages.success(request, '添加成功')return render(request,"userinfo/user_edit.html",{"form":form})print(form.errors)return render(request,"userinfo/user_edit.html",{"form":form})
    
  6. 验证用户名不能重复

    def clean_username(self):username = self.cleaned_data.get("username")user = models.User.objects.filter(username=username).first()if user:raise forms.ValidationError("用户名已存在")return username
    
  7. 控制员工选择框只能选择没有创建用户的人员

    def __init__(self,*args,**kwargs):super().__init__(*args,**kwargs)user_obj = models.User.objects.all()user_id_list = [obj.employee_id for obj in user_obj]self.fields['employee'].queryset = Employee.objects.exclude(id__in=user_id_list)for name,field in self.fields.items():field.widget.attrs.update({"class":"layui-input","placeholder":"输入"+field.label})
    

对数据库中的密码进行加密

MD5简介

MD5加密算法是一种单向加密算法,是不可逆的一种的加密方式。MD5算法简要的叙述可以为:MD5以512位分组来处理输入的信息,且每一分组又被划分为16个32位子分组,经过了一系列的处理后,算法的输出由四个32位分组组成,将这四个32位分组级联后将生成一个128位散列值。

加密实现

  1. 建立encryption.py文件

  2. 建立md5加密算法函数

    import hashlib
    from django.conf import settings
    def MD5(str):obj = hashlib.md5(settings.SECRET_KEY.encode('utf-8'))obj.update(str.encode('utf-8'))return obj.hexdigest()
    
  3. 修改视图函数

    form.instance.password = MD5(settings.DEFAULT_PASSWORD)
    

实现密码重置

  1. 表格行操作模板

    <!-- 表格操作模板 -->
    <script type="text/html" id="TableBar"><div class="layui-clear-space"><a class="layui-btn layui-btn-xs " lay-event="reset"><i class="layui-icon layui-icon-edit"></i>重置密码</a><a class="layui-btn layui-btn-xs layui-bg-red" lay-event="delete"><i class="layui-icon layui-icon-delete"></i>删除</a></div>
    </script>
    
  2. 建立重置密码视图函数

    # 重置密码
    @csrf_exempt
    def reset_password(request):id = request.POST.get("id") #用户idpassword = MD5(settings.DEFAULT_PASSWORD)User.objects.filter(id=id).update(password=password)return res_json_data.success_api()
    
  3. 通过ajax实现密码重置

    // 单元格事件
    table.on('tool(TableFilter)', function (obj) {var data = obj.data; //获得当前行数据if (obj.event === 'reset') {layer.confirm('确认重置为默认密码吗?', {btn: ['确定', '取消'] //按钮}, function(index){$.post('/user/reset/', {"id":data.id},function(data){if (data.success) {layer.msg(data.msg);}})});}
    });
    

    jQuery get() 和 post() 方法用于通过 HTTP GET 或 POST 请求从服务器请求数据。

    语法:$.get( URL [, data ] [, callback ] [, dataType ] )

    • URL:发送请求的 URL字符串。
    • data:可选的,发送给服务器的字符串或 key/value 键值对(字典)。
    • callback:可选的,请求成功后执行的回调函数。
    • dataType:可选的,从服务器返回的数据类型。默认:智能猜测(可以是xml, json, script, 或 html)。

用户登录的实现

界面原型

在这里插入图片描述

代码实现

  1. 用户登录路由path("",user_views.user_login)

  2. 登录视图函数

    # 用户登录
    def user_login(request):if request.method == "GET":form = user_form.login_form()return render(request,"userinfo/login.html",{"form":form})
    
  3. 用户登录页面模板

    {% load static %}
    <!DOCTYPE html>
    <html>
    <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>员工信息管理系统</title><link href="{%static 'layui/css/layui.css'%}" rel="stylesheet"><style>body {background:url("{% static 'loginbg.png'%}") 0% 0% / cover no-repeat;font-size:12px;}.main-body {top:50%;left:50%;position:absolute;transform:translate(-50%,-50%);overflow:hidden;width: 428px;background-color: #fff;border-radius:12px;}.login-top {height:117px;background-color:#148be4;border-radius:12px 12px 0 0;font-size:30px;font-weight:400;font-stretch:normal;color:#fff;line-height:117px;text-align:center;overflow:hidden;}.login-top .bg1 {display:inline-block;width:74px;height:74px;opacity:.1;border-radius:0 74px 0 0;position:absolute;left:0;top:43px;background-color: #fff;}.login-top .bg2 {display:inline-block;width:94px;height:94px;opacity:.1;border-radius:50%;position:absolute;right:-16px;top:-16px;background-color: #fff;}.center {width:288px;margin:0 auto;padding-top:40px;padding-bottom:15px;position:relative;}.login-btn {width:288px;height:40px;background-color:#1E9FFF;border-radius:16px;margin:24px auto 0;text-align:center;line-height:40px;color:#fff;font-size:14px;letter-spacing:0;cursor:pointer;border:none;}.center {width:288px;margin:0 auto;padding-top:40px;padding-bottom:15px;position:relative;}</style>
    </head>
    <body><div class="main-body"><div class="login-top"><span>员工信息管理系统</span><span class="bg1"></span><span class="bg2"></span></div></div><script src="{%static 'layui/layui.js'%}"></script>
    <script>
    layui.use(function(){var $ = layui.jquery;var layer = layui.layer;{% for msg in messages %}layer.alert('{{ msg}}');{% endfor %}
    });     
    </script>
    </body>
    </html>
    

    绝对定位布局(position)

    1. 定位方式属性
      • static 默认,元素在文档常规流中当前的布局位置
      • relative :不会脱离文档流,不会浮起来,一般为里面的absolute 元素提供定位依据
      • absolute 元素会被移出正常文档流,相对于上一个绝对定位的父元素来进行定位
      • fixed 元素会被移出正常文档流,相对于屏幕视口(viewport)的位置来指定元素位置
    2. absolute相对定位详解
      • 父元素没有设置相对定位或绝对定位的情况下,元素相对于根元素定位(即html元素)
      • 父元素设置了相对定位或绝对定位,元素会相对于离自己最近的设置了相对或绝对定位的父元素进行定位
    3. 定位属性
      • top样式属性定义了定位元素的上外边距边界与其包含块上边界之间的偏移
      • bottom 定位元素下外边距边界与其包含块下边界之间的偏移
      • left 定位元素的上外边距边界与其包含块上边界之间的偏移
      • right 定位元素的右外边距边界与其包含块右边界之间的偏移
      • transform: translate(12px, 50%); 水平平移,第一个参数对应X轴,第二个参数对应Y轴。如果第二个参数未提供,则默认值为0,注意参数用逗号分隔
  4. 用户登录表单类

    # 登录表单类
    class login_form(forms.ModelForm):class Meta:model =models.Userfields = ['username','password']widgets ={'password':forms.PasswordInput(attrs={"lay-affix":"eye"},render_value=True),}def clean_password(self):password = self.cleaned_data.get("password")return MD5(password)def __init__(self,*args,**kwargs):super().__init__(*args,**kwargs)for name,field in self.fields.items():field.widget.attrs.update({"class":"layui-input","placeholder":"输入"+field.label})
    
    • render_value=True ——保持上次输入的值
  5. 修改视图函数,进行用户登录验证

    # 用户登录
    def user_login(request):if request.method == "GET":form = user_form.login_form()return render(request,"userinfo/login.html",{"form":form})form = user_form.login_form(data=request.POST)if form.is_valid():print(form.cleaned_data,"===校验完成") #打印form提交的所有数据user_obj = User.objects.filter(**form.cleaned_data).first()if not user_obj:messages.warning(request, '用户名或密码错误')return render(request,"userinfo/login.html",{"form":form})# 登录成功return redirect("/employee/list/")print(form.errors)return render(request,"userinfo/login.html",{"form":form})
    

是否登录检验

会话Session

  1. 简介

    Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。Session 对象最常见的一个用法就是存储用户的首选项。

  2. 操作语法

    • 设置session,通过request.session字典

      request.session['user_info'] = {'id':user_obj.id,'user_id':user_obj.id_number,'user_name':user_obj.user_name,'role_id':user_obj.role_id,
      }
      
    • session有效期设置

      request.session.set_expiry(value)

      • 如果value是个整数,session会在设置秒数后失效。
      • 如果value是个datatimetimedelta,session就会在这个时间后失效。
      • 如果value是0,用户关闭浏览器session就会失效。//我们用的就是这种方式
      • 如果value是None,session会依赖全局session失效策略。
    • 获取session值

      后端:user_info = request.session.get('user_info')

      前端:request.session.user_info.name

修改代码实现访问授权

  1. 通过session记录登录用户信息

    # 登录成功
    request.session["user_info"] = {"id":user_obj.id,"username":user_obj.username,"name":user_obj.employee.name,
    }
    request.session.set_expiry(0)
    return redirect("/employee/list/")
    
  2. 用户登录状态验证

    user_info = request.session.get("user_info")
    print(user_info,"==用户信息")
    if not user_info:return redirect("/")
    

中间件

中间件在Django中是一种轻量级、底层的“插件”系统,用于全局地处理请求和响应。它位于Django的请求和响应处理过程之间,可以对HTTP请求和响应进行预处理和后处理,从而实现诸如权限控制、日志记录、数据压缩、缓存等功能。

中间件的请求流程:

在这里插入图片描述

用中间件进行登录验证拦截

  1. 建立auth.py文件,创建中间件类

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import redirect
    from datetime import datetime
    class AuthMiddleware(MiddlewareMixin):def process_request(self, request):print("===访问地址:",request.path,datetime.now())user_info = request.session.get('user_info')print(user_info,"==登陆用户信息")if  user_info:returnreturn redirect("/")
    
  2. 在setting中注册中间件

    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','userinfo.auth.AuthMiddleware',
    ]
    
    • 第9行:注册中间件
  3. 处理302错误,重定向错误

    class AuthMiddleware(MiddlewareMixin):def process_request(self, request):print("===访问地址:",request.path,datetime.now())pass_urls = ['/']if request.path  in pass_urls:returnuser_info = request.session.get('user_info')print(user_info,"==登陆用户信息")if  user_info:returnreturn redirect("/")
    
    • return 没有返回值,将进行放行,否则将进行拦截

注销和密码修改

注销操作

  1. 修改公共模板页面添加用户信息和菜单。

    <li class="layui-nav-item" style="float: right;"><a href="javascript:void(0);"><img src="https://unpkg.com/outeres@0.0.10/demo/avatar/1.jpg" class="layui-nav-img">{{request.session.user_info.name}}</a><dl class="layui-nav-child"><dd><a href="">修改密码</a></dd><dd><a href="/user/logout/">退出</a></dd></dl>
    </li>
    
  2. 添加注销视图函数

    # 用户退出
    def user_logout(request):request.session.clear()return redirect("/")
    

密码修改

  1. 创建单行编辑模版页面single_edit_dlg.html

    {%extends 'common/layout_dlg.html'%}
    {% block css %}
    <style>.layui-input-block{margin-left: 150px; }.layui-form-label{width: 120px;}
    </style>
    {%endblock%}
    {%block content%}
    <div class="layui-card-body"><form class="layui-form"  method="post" novalidate>{% csrf_token %}{% for field in form %}<div class="layui-form-item">{% if field.field.required %}<label class="layui-form-label label-required-next">{{ field.label }}:</label>{% else %}<label class="layui-form-label">{{ field.label }}:</label>{% endif %}<div class="layui-input-block">{{ field }}<span style="color: red">{{ field.errors.0 }}</span></div></div>{% endfor %}<div class="layui-form-item"><div class="layui-input-block"><button type="submit" class="layui-btn" lay-submit>确认提交</button></div></div></form>
    </div>
    {% endblock %}
    {%block js%}
    {% block extendsjs %}{% endblock %}
    {% for msg in messages %}
    <script>layui.use(['layer'], function () {var iconValue = "{{msg.tags}}" == 'success' ? 1 : 2;layer.msg('{{msg}}',{ icon: iconValue, time: 2000 },function (){if( "{{msg.tags}}" == 'success' ){parent.layer.close(parent.layer.getFrameIndex(window.name)); //关闭当前页parent.layui.table.reload('TableId');//重新加载父窗口表格}})})
    </script>
    {% endfor %}
    {% endblock %}
    
  2. 创建密码修改表单类

    # 密码修改表单类
    class password_form(forms.ModelForm):confirm_password = forms.CharField(label="确认新密码",required=True,widget=forms.PasswordInput(render_value=True,attrs={"lay-affix":"eye"}))new_password = forms.CharField(label="新密码",required=True,widget=forms.PasswordInput(render_value=True,attrs={"lay-affix":"eye"}))class Meta:model =models.Userfields = ['username','password','new_password','confirm_password']widgets ={'password':forms.PasswordInput(attrs={"lay-affix":"eye"},render_value=True),}def __init__(self,*args,**kwargs):super().__init__(*args,**kwargs)for name,field in self.fields.items():field.widget.attrs.update({"class":"layui-input","placeholder":"输入"+field.label})
    
  3. 完善密码修改视图函数

    # 修改密码
    def change_password(request):if request.method == "GET":form = user_form.password_form()return render(request,"common/single_edit_dlg.html",{"form":form})user_info = request.session['user_info']user_id = user_info['id']row_obj = User.objects.filter(id=user_id).first()form = user_form.password_form(data=request.POST)if form.is_valid():username = form.cleaned_data['username']password = MD5(form.cleaned_data['password'])if row_obj.username != username or row_obj.password!=password:messages.error(request, '用户名或密码不正确')return render(request,"common/single_edit_dlg.html",{"form":form})if form.cleaned_data['new_password']!= form.cleaned_data['confirm_password']:messages.error(request, '两次密码输入不一致')return render(request,"common/single_edit_dlg.html",{"form":form})new_password = MD5(form.cleaned_data['new_password'])User.objects.filter(id=user_id).update(password=new_password)messages.success(request, '修改成功')return render(request,"common/single_edit_dlg.html",{"form":form})return render(request,"common/single_edit_dlg.html",{"form":form})
    

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

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

相关文章

算法笔记()

文章目录 什么是算法算法的分类算法的意义 其他比较好的算法网站比较知名的算法博主 算法这个课题有点太大了&#xff0c;穷尽一生也难以望其涯岸那是肯定的&#xff0c;甚至几代人无数精英也做不到完全掌握&#xff0c;我们普通人就更不要想了&#xff0c;能理解多少算多少吧。…

BugKu练习记录:矛盾

题目&#xff1a; $num$_GET[num]; if(!is_numeric($num)) { echo $num; if($num1) echo flag{**********}; }关键在于绕过is_numeric&#xff0c;PHP中字符串与数字弱比较&#xff0c;会将字符串转换为数字&#xff0c;截至到非数字字符&#xff0c;如果第一个字符就是非数字…

【Nas】X-DOC:在Mac OS X 中使用 WOL 命令唤醒局域网内 PVE 主机

【Nas】X-DOC&#xff1a;在Mac OS X 中使用 WOL 命令唤醒局域网内 PVE 主机 1、Mac OS X 端2、PVE 端&#xff08;Debian Linux&#xff09; 1、Mac OS X 端 &#xff08;1&#xff09;安装 wakeonlan 工具 brew install wakeonlan&#xff08;2&#xff09;唤醒 PVE 命令 …

8.3.2 前向分步算法与 AdaBoost

由前向分步算法可以推导出 AdaBoost&#xff0c;用定理叙述这一关系。   定理 8.3  AdaBoost 算法是前向分步加法算法的特例。 这时&#xff0c;模型是由基本分类器组成的加法模型&#xff0c;损失函数是指数函数。   证明 前向分步算法学习的正加法模型&#xff0c;当基…

batc和mini-batch

一、概念介绍 batch 批处理&#xff0c;在机器学习中&#xff0c;batch 是指一次处理整个训练数据集的方式。例如&#xff0c;如果有 1000 个训练样本&#xff0c;使用 batch 训练时&#xff0c;模型会同时使用这 1000 个样本进行一次参数更新。也就是说&#xff0c;计算损失…

Java学习教程,从入门到精通,Java for循环知识点(15)

1、Java for循环 在Java中&#xff0c;for循环是一种基本的循环控制结构&#xff0c;它允许你重复执行一段代码固定次数。for循环的语法如下&#xff1a; for (初始化表达式; 循环条件; 迭代表达式) {// 循环体&#xff1a;要重复执行的代码块 }这里是每个部分的详细解释&…

安宝特分享 | AR技术引领:跨国工业远程协作创新模式

在当今高度互联的工业环境中&#xff0c;跨国合作与沟通变得日益重要。然而&#xff0c;语言障碍常常成为高效协作的绊脚石。安宝特AR眼镜凭借其强大的多语言自动翻译和播报功能&#xff0c;正在改变这一局面&#xff0c;让远程协作变得更加顺畅。 01 多语言翻译优势 安宝特A…

生物信息与机器学习6 - 有监督学习算法和无监督学习算法

1.有监督学习算法 有监督学习算法推荐&#xff1a; 决策树分类器 - 适合处理分类问题&#xff0c;容易理解和可视化&#xff1b; KNN分类器 - 对于简单的单特征分类也很有效&#xff1b; 逻辑回归 (多分类) - 使用one-vs-all策略处理多类别。 有监督学习的选择&#xff1a; 如…

【Nas】X-DOC:Mac mini Docker部署小雅Alist

【Nas】X-DOC&#xff1a;Mac mini Docker部署小雅Alist 1、拉取镜像&#xff1a;2、获取阿里云盘信息3、启动容器4、访问服务5、定时清理阿里云盘缓存 1、拉取镜像&#xff1a; docker pull xiaoyaliu/alist:latest2、获取阿里云盘信息 mkdir /Volumes/Data/Docker/xiaoya在…

【数据结构】静态和动态空间管理

让我们来聊聊动态空间管理和静态空间管理&#xff0c;这两个听起来有点复杂的词。其实&#xff0c;它们就像你在学校里玩和学习时用的工具&#xff0c;只不过是在计算机里怎么使用“空间”的工具。我们来一起看看吧&#xff01; ### 什么是静态空间管理&#xff1f; 想象一下…

逗号运算符应用举例

在main.cpp里输入程序如下&#xff1a; #include <iostream> //使能cin(),cout(); #include <iomanip> //使能setbase(),setfill(),setw(),setprecision(),setiosflags()和resetiosflags(); //setbase( char x )是设置输出数字的基数,如输出进制数则用set…

依赖注入(Dependency Injection, DI)和控制反转(Inversion of Control, IoC)

依赖注入&#xff08;Dependency Injection, DI&#xff09;和控制反转&#xff08;Inversion of Control, IoC&#xff09;是面向对象设计中两个紧密相关的概念&#xff0c;特别是在构建可扩展和可维护的软件系统时非常有用。它们主要用于减少代码之间的耦合度&#xff0c;提高…

vxe-table v4.8+ 与 v3.10+ 虚拟滚动支持动态行高,虚拟渲染更快了

Vxe UI vue vxe-table v4.8 与 v3.10 解决了老版本虚拟滚动不支持动态行高的问题&#xff0c;重构了虚拟渲染&#xff0c;渲染性能大幅提升了&#xff0c;行高自适应和列宽拖动都支持&#xff0c;大幅降低虚拟渲染过程中的滚动白屏&#xff0c;大量数据列表滚动更加流畅。 自适…

ICPC区域赛成都站【赛后回顾+总结】

传送门 前言赛后总结赛后回顾赛后感悟 前言 首先&#xff0c;这是本人本赛季第一场XCPC区域赛&#xff0c;也是本人算竞生涯中第一场XCPC区域赛&#xff08;之前只打过邀请赛和省赛&#xff09;。 赛后总结 然后赛后总结一下&#xff1a;我队天崩开局&#xff0c;我队出师不利…

Vue Scoped CSS深度解析:原理、误区与最佳实践

引言 在Vue开发中&#xff0c;Scoped CSS是一个强大而复杂的功能。它允许我们将样式限制在特定组件内&#xff0c;但同时也带来了一些细微的行为&#xff0c;可能导致意外的样式"泄漏"。本文将深入探讨Vue Scoped CSS的工作原理&#xff0c;解释常见的误区&#xff…

c盘满了怎么清理垃圾而不误删?6招轻松清理C盘,快来试试

c盘满了怎么清理垃圾而不误删&#xff1f;相信平时工作生活中离不开电脑&#xff0c;随着使用电脑时间就了&#xff0c;C 盘的空间会不断被占据&#xff0c;进而致使系统运行变得迟缓&#xff0c;甚至出现卡顿现象。因此&#xff0c;定期清理 C 盘的是非常重要的。很多电脑小白…

excel的宏1

1宏和vba visual basic for applications 一种编程语言 2vba编写一系列指令的程序&#xff0c;就是宏 3完成重复性的数据任务 点击开发工具 使用设置的宏之后表格的变化 excel帮忙编写了一个代码 以上为自动编写的代码

VB.NET中如何利用WCF(Windows Communication Foundation)进行服务间通信

在VB.NET中&#xff0c;Windows Communication Foundation (WCF) 是一个用于构建安全、可靠和跨平台的分布式系统的框架。WCF 提供了多种服务通信选项&#xff0c;包括 HTTP、TCP、命名管道和 MSMQ 等传输协议&#xff0c;以及多种消息编码格式&#xff08;如文本和二进制&…

Swarm-LIO: Decentralized Swarm LiDAR-inertial Odometry论文翻译

文章目录 前言一、介绍二、相关工作三、方法A. 问题表述B. 框架概述C. 群体系统的初始化D. 去中心化激光雷达-惯性状态估计 四. 实验A. 室内飞行B. 退化环境飞行C. 去中心化部署 五. 结论和未来工作 前言 原文&#xff1a;原文 准确的自我状态和相对状态估计是完成群体任务的关…

光耦合器的关键作用和创新---腾恩科技

光耦合器或光隔离器已成为电路中必不可少的器件&#xff0c;它允许信号在无需直接电接触的情况下跨不同电压域传输。这种隔离能力对于保护低压元件免受高压电路的潜在损坏至关重要。本文将仔细研究光耦合器在当今技术中发挥的独特作用&#xff0c;并探讨其在各种应用中不断扩展…