【玩转全栈】----基于ModelForm完成用户管理页面

        

目录

大致效果

添加用户代码

引入ModelForm

ModelForm 与一般表单的区别:

ModelForm 与传统 Form 的区别:

使用ModelForm制作用户管理

新建用户

编辑用户:

删除数据

完整代码

        在学完前面的部门管理案例后,自己独立写出个用户管理应该不难,基本逻辑和大致代码都和前面一样,大家可以自己试试。

大致效果

        

基于ModelForm用户管理 系统

       

添加用户代码

        但是,按照之前的方式写的话,在表单方面还是会有些繁琐,这里指的是后端代码和前端html。因为用户表涉及到的字段有很多,这就导致视图函数中要写很多行接收用户提交数据,而且添加用户的前端页面也会非常长。像之前那些写的话,用户添加相关文件就会是这样的:

user_list.html:

{% extends 'layout.html' %}
{% block content %}<div class="container-fluid"><div class="my-div"><div style="margin-bottom: 10px"><a class="btn btn-primary" href="/user/add/">{#            target="_blank"使得跳转打开新页面#}<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新建用户</a></div><div><div class="panel-heading"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>用户列表</div><div class="bs-example" data-example-id="contextual-table"><table class="table"><thead><tr><th>ID</th><th>姓名</th><th>密码</th><th>年龄</th><th>账户余额</th><th>入职时间</th><th>性别</th><th>部门</th><th>操作</th></tr></thead><tbody>{% for obj in queryset %}<tr><th scope="row">{{ obj.id }}</th><td>{{ obj.name }}</td><td>{{ obj.password }}</td><td>{{ obj.age }}</td><td>{{ obj.account }}</td><td>{{ obj.create_time|date:"Y-m-d H:i:s" }}</td>
{#                        creat_time也是,Django内部自带的一种写法,相当于在内部建立一个date函数,将匹配模板和create_time作为参数传递进去,也不允许加百分号#}
{#                      <td>{{ obj.depart_id }}</td>#}
{#                        在模板语法中不允许自己加(),如果是要括号的,模板会自动帮你加#}<td>{{ obj.get_gender_display }}</td># Django内部提供了一种方法,对应models.py中带有choices属性的字段,要是想要获取对应元组的内容,只需要使用  get_内容_display<td>{{ obj.depart.title }}</td><td><a class="btn btn-primary btn-xs" href="">编辑</a><a class="btn btn-danger btn-xs" href="">删除</a></td></tr>{% endfor %}</table></div></div></div></div>
{% endblock %}

user_add.html:

{% extends 'layout.html' %}
{% block content %}<div class="container-fluid" style="margin-top: 10px"><div class="my-div"><div class="container"><div class="panel panel-default" style="width: 750px;margin-top: 10px"><!-- Default panel contents --><div class="panel-heading" style="margin-top: 0">新建 用户</div><div class="panel-body"><form class="form-horizontal" method="POST">{% csrf_token %}<!-- 姓名输入框 --><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">姓名</label><div class="col-sm-5"><input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入姓名" name="name"></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">密码</label><div class="col-sm-5"><input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入密码" name="pwd"></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">年龄</label><div class="col-sm-5"><input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入年龄" name="age"></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">余额</label><div class="col-sm-5"><input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入账户余额" name="account"></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">入职时间</label><div class="col-sm-5"><input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入入职时间" name="ctime"></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">性别</label><div class="col-sm-5"><label><select class="form-control" name="gender">{% for item in gender_choices %}<option value={{ item.0 }}>{{ item.1 }}</option>{% endfor %}</select></label></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">部门</label><div class="col-sm-5"><label><select class="form-control" name="depart">{% for item in queryset %}<option value="{{ item.id }}">{{ item.title }}</option>{% endfor %}</select></label></div></div><!-- 管理员密码输入框 --><div class="form-group"><label for="inputPassword3" class="col-sm-2 control-label">管理员密码</label><div class="col-sm-10"><input type="password" class="form-control" id="inputPassword3" placeholder="请输入管理员密码" name="pwd"></div></div><!-- 提交按钮 --><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><button type="submit" class="btn btn-primary">提 交</button></div></div></form></div></div></div></div>
</div>
{% endblock %}

views.py:

def user_list(request):# 获取用户列表queryset = UserInfo.objects.all()return render(request, "user_list.html",{"queryset":queryset})def user_add(request):Department.objects.all()context = {'gender_choices': UserInfo.gender_choices,'queryset': Department.objects.all()}if request.method == "GET":return render(request, "user_add.html",context)name = request.POST.get("name")pwd = request.POST.get("pwd")age = request.POST.get("age")account = request.POST.get("account")ctype = request.POST.get("ctime")gender = request.POST.get("gender")depart_id = request.POST.get("depart")UserInfo.objects.create(name=name,password=pwd, age=age, account=account, create_time=ctype, depart_id =depart_id, gender=gender)return redirect("/user/list")

引入ModelForm

下面介绍一种更加便捷的表单方法——ModelForm

        在Django开发中,ModelForm 是 Django 提供的一个用于简化表单处理的工具,它能通过模型(Model)自动生成表单,而不需要手动定义每个字段。ModelForm 是 Django 中的一个强大功能,能够帮助开发者减少重复的代码,特别是在需要处理与模型关联的表单时。

ModelForm 与一般表单的区别:

特性ModelForm一般表单
自动与数据库字段绑定自动与模型字段绑定不会自动绑定,字段需要手动定义
字段映射字段通过模型自动映射到表单字段需要手动创建字段并定义属性
验证机制自动应用模型中的验证规则需要手动编写字段的验证逻辑
数据保存自动保存到数据库需要手动处理数据保存逻辑
创建表单字段自动生成字段需要手动定义表单字段

ModelForm 是由传统Form更新而来,继承了Form,但会更加便捷一点

ModelForm 与传统 Form 的区别:

特性ModelForm传统 Form
关联模型自动与模型字段关联不关联模型,需要手动定义字段
字段定义通过模型字段自动生成需要手动定义所有字段
验证机制自动继承模型的验证规则需要手动为每个字段定义验证规则
数据保存自动将表单数据保存到模型实例需要手动提取数据并保存到数据库
生成表单字段自动生成HTML表单字段需要手动创建表单字段

    ModelForm 主要用于那些与模型直接关联的表单,简化了表单字段的定义和数据的保存过程。与传统的 Form 相比,ModelForm 自动从模型中获取字段和验证规则,因此减少了开发工作量。缺点是对于那些没有直接模型支持的表单,或者需要更复杂逻辑的表单,ModelForm 可能不如手动定义的传统 Form 灵活。

使用ModelForm制作用户管理

新建用户

"""ModelForm示例"""
# 引入forms
from django import forms
class UserForm(forms.ModelForm):# 继承ModelFormclass Meta:# model等于表名model = UserInfo# 具体要用到的列名fields = ['name','password','age','account','create_time','depart','gender']def user_m_form_add(request):"""添加用户,ModelForm版本"""# 实例化前面的ModelFormform = UserForm()return render(request, "user_MForm_add.html",{"form":form})

简单得在html文件中运用:

<form class="form-horizontal" method="POST">{% csrf_token %}<!-- 输入框 -->{% for items in form %}{{ items.label }} : {{ items }}{% endfor %}<!-- 提交按钮 --><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><button type="submit" class="btn btn-primary">提 交</button></div></div></form>

这样的话,页面显示的就是前面ModelForm中创建的fields中的列:

        这样的话,数字数据输入框会自动加一个加减箭头,性别会自动加男女选项下拉框,部门也会自动加关联部门表中的id下拉框。但我们想要的效果是部门处要是具体的部门,而不是对应的id,因为ModelForm在循环取值过程中,取到的是一个一个的对象,若直接print这个对象,就会是这样的效果:

        可以在部门表后面加上_ _str_ _方法,作用是使得外部有地方直接打印对象时,会打印_ _str_ _函数中返回的内容,这里是部门id所对应的title名称。

def __str__(self):return self.title

        这里的 { { items.label }},取的是标签,即字段的另一个名称,在models文件中的verbose_name参数即是友好的中文名称,{ { items.label }}可以使得遍历每个字段并创建输入框时在前面加字段的另一名称。

 name = models.CharField(verbose_name="姓名",max_length=32)

但是这样生成的页面和原来手写的页面还是有点不一样

这是因为虽然ModelForm能简化我们的步骤,但是他是统一自动生成的html标签,样式格式是不会变的,怎么解决呢?

可以在UserForm中添加widgets插件

有两种方式添加:

1、在Meta中添加

添加widgets插件:

widgets = {'name': forms.TextInput(attrs={'class':'form-control'}),'password': forms.PasswordInput(attrs={'class':'form-control'}),}

但是这样,如果字段足够多的情况下,还是得一行一行写,也比较繁琐。

2、重写init方法

    def __init__(self,*args,**kwargs):super(UserForm,self).__init__(*args,**kwargs)# 循环找到所有的插件for name,field in self.fields.items():field.widget.attrs = {'class':'form-control'}

这段代码通过循环找到所有的字段名,再赋予样式。

编辑用户:

        编辑用户和部门表的编辑一样,只需要将用户点击编辑行数据展示出来,然后用户修改,自动更新,并跳转到显示页面上。

当然这是一般的方法,使用ModelForm的话会更加便捷。

        还是使用前面新建数据创建的ModelForm,只需创建实例即可使用。将用户点击编辑行的id传给视图函数,创建实例传参instance=根据id获取到的数据对象,这样即可在输入框中显示原始数据;用UserForm接收用户提交的数据,使用ModelForm的form.save()函数进行更新,这比直接写更新语句要便捷得多,但是这样会导致一个问题,即程序并不知道要更新的是哪行数据,所有程序会自动将用户添加数据作为一个新数据添加到数据库中,并且原来的数据不变,这并不是我们想要的结果,解决方法也很简单,只需要再次获取到ID对应数据对象,在UserForm中添加参数instance=数据对象,再更新,即可实现便捷。

def user_edit(request,nid):row_object = UserInfo.objects.filter(id=nid).first()if request.method == "GET":# 根据ID去数据库获取要编辑的那一行数据(对象)# 加上instance=row_object会默认将对应ID的数据显示到页面输入框中,这就比之前的部门管理要方便很多form = UserForm(instance=row_object)return render(request,"user_edit.html",{"form":form})# 如果不加下面这行代码,并且UserForm中加instance,那么数据库中就不是更新数据,因为程序不知道要更新哪一行数据,所有程序会自动新添加一行数据,原来数据保持不变form = UserForm(data=request.POST,instance=row_object)if form.is_valid():form.save()return redirect("/user/list/")return render(request,"user_edit.html",{"form":form})

删除数据

由于删除数据本身就比较简洁了,不必追求花样,用部门管理中的删除逻辑就行:

view.py

def user_delete(request,nid):UserInfo.objects.filter(id=nid).delete()return redirect("/user/list/")

完整代码

urls.py:

# 用户管理path("user/list/", views.user_list),path("user/add/", views.user_add),path("user/MForm_add/", views.user_m_form_add),path("user/<int:nid>/edit/", views.user_edit),path("user/<int:nid>/delete/", views.user_delete),

views.py:

def user_list(request):# 获取用户列表queryset = UserInfo.objects.all()for obj in queryset:# Django内部提供了一种方法,对应models.py中带有choices属性的字段,要是想要获取对应元组的内容,只需要使用  get_内容_display()函数,# 就是自动获取到元素对应元组中的内容,在html中不是函数,在视图函数中是函数# print(obj.get_gender_display())# print(obj.create_time.strftime("%Y-%m-%d"))# ids = Department.objects.filter(id=obj.depart_id).first()# print(ids.title)# 像这样按照id去部门表中查找title值当然是可以的,但Django内部提供了一种更加便捷的方式,用于多表间的关联# 帮助跨表,获取数据很容易var = obj.depart.titleprint(var)return render(request, "user_list.html",{"queryset":queryset})def user_add(request):Department.objects.all()context = {'gender_choices': UserInfo.gender_choices,'queryset': Department.objects.all()}if request.method == "GET":return render(request, "user_add.html",context)name = request.POST.get("name")pwd = request.POST.get("pwd")age = request.POST.get("age")account = request.POST.get("account")ctype = request.POST.get("ctime")gender = request.POST.get("gender")depart_id = request.POST.get("depart")UserInfo.objects.create(name=name,password=pwd, age=age, account=account, create_time=ctype, depart_id =depart_id, gender=gender)return redirect("/user/list")"""ModelForm示例"""from django import forms
class UserForm(forms.ModelForm):class Meta:model = UserInfofields = ['name','password','age','account','create_time','depart','gender']# 1、还是比较繁琐# widgets = {#     'name': forms.TextInput(attrs={'class':'form-control'}),#     'password': forms.PasswordInput(attrs={'class':'form-control'}),# }# 2、循环到所有的插件再赋予form-control样式def __init__(self,*args,**kwargs):super(UserForm,self).__init__(*args,**kwargs)# 循环找到所有的插件for name,field in self.fields.items():field.widget.attrs = {'class':'form-control'}
def user_m_form_add(request):"""添加用户,ModelForm版本"""if request.method == "GET":form = UserForm()return render(request, "user_MForm_add.html",{"form":form})# 用户提交POST请求,校验数据form = UserForm(data=request.POST)# 注意!要是数据填写错误,表单数据就传不过来print(request.POST)if form.is_valid():print(form.cleaned_data)# 自动帮我们保存到ModelForm定义的数据库中form.save()return redirect("/user/list")else:print(form.errors)def user_edit(request,nid):row_object = UserInfo.objects.filter(id=nid).first()if request.method == "GET":# 根据ID去数据库获取要编辑的那一行数据(对象)# 加上instance=row_object会默认将对应ID的数据显示到页面输入框中,这就比之前的部门管理要方便很多form = UserForm(instance=row_object)return render(request,"user_edit.html",{"form":form})# 如果不加下面这行代码,并且UserForm中加instance,那么数据库中就不是更新数据,因为程序不知道要更新哪一行数据,所有程序会自动新添加一行数据,原来数据保持不变form = UserForm(data=request.POST,instance=row_object)if form.is_valid():form.save()return redirect("/user/list/")return render(request,"user_edit.html",{"form":form})def user_delete(request,nid):UserInfo.objects.filter(id=nid).delete()return redirect("/user/list/")

user_list.html:

{% extends 'layout.html' %}
{% block content %}<div class="container-fluid"><div class="my-div">
{#            <div style="margin-bottom: 10px">#}
{#                <a class="btn btn-primary" href="/user/add/">#}{#            target="_blank"使得跳转打开新页面#}
{#                    <span class="glyphicon glyphicon-plus" aria-hidden="true"></span>#}
{#                    新建用户</a>#}
{#            </div>#}<div style="margin-bottom: 10px"><a class="btn btn-primary" href="/user/MForm_add/">{#            target="_blank"使得跳转打开新页面#}<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>新建用户</a></div><div><div class="panel-heading"><span class="glyphicon glyphicon-eye-open" aria-hidden="true"></span>用户列表</div><div class="bs-example" data-example-id="contextual-table"><table class="table"><thead><tr><th>ID</th><th>姓名</th><th>密码</th><th>年龄</th><th>账户余额</th><th>入职时间</th><th>性别</th><th>部门</th><th>操作</th></tr></thead><tbody>{% for obj in queryset %}<tr><th scope="row">{{ obj.id }}</th><td>{{ obj.name }}</td><td>{{ obj.password }}</td><td>{{ obj.age }}</td><td>{{ obj.account }}</td><td>{{ obj.create_time|date:"Y-m-d" }}</td>
{#                        creat_time也是,Django内部自带的一种写法,相当于在内部建立一个date函数,将匹配模板和create_time作为参数传递进去,也不允许加百分号#}
{#                      <td>{{ obj.depart_id }}</td>#}
{#                        在模板语法中不允许自己加(),如果是要括号的,模板会自动帮你加#}<td>{{ obj.get_gender_display }}</td><td>{{ obj.depart.title }}</td><td><a class="btn btn-primary btn-xs" href="/user/{{ obj.id }}/edit/">编辑</a><a class="btn btn-danger btn-xs" href="/user/{{ obj.id }}/delete/">删除</a></td></tr>{% endfor %}</table></div></div></div></div>
{% endblock %}

user_add.html:

{% extends 'layout.html' %}
{% block content %}<div class="container-fluid" style="margin-top: 10px"><div class="my-div"><div class="container"><div class="panel panel-default" style="width: 750px;margin-top: 10px"><!-- Default panel contents --><div class="panel-heading" style="margin-top: 0">新建 用户</div><div class="panel-body"><form class="form-horizontal" method="POST">{% csrf_token %}<!-- 姓名输入框 --><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">姓名</label><div class="col-sm-5"><input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入姓名" name="name"></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">密码</label><div class="col-sm-5"><input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入密码" name="pwd"></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">年龄</label><div class="col-sm-5"><input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入年龄" name="age"></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">余额</label><div class="col-sm-5"><input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入账户余额" name="account"></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">入职时间</label><div class="col-sm-5"><input type="text" class="form-control" id="inputDepartmentName" placeholder="请输入入职时间" name="ctime"></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">性别</label><div class="col-sm-5"><label><select class="form-control" name="gender">{% for item in gender_choices %}<option value={{ item.0 }}>{{ item.1 }}</option>{% endfor %}</select></label></div></div><div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">部门</label><div class="col-sm-5"><label><select class="form-control" name="depart">{% for item in queryset %}<option value="{{ item.id }}">{{ item.title }}</option>{% endfor %}</select></label></div></div><!-- 管理员密码输入框 --><div class="form-group"><label for="inputPassword3" class="col-sm-2 control-label">管理员密码</label><div class="col-sm-10"><input type="password" class="form-control" id="inputPassword3" placeholder="请输入管理员密码" name="pwd"></div></div><!-- 提交按钮 --><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><button type="submit" class="btn btn-primary">提 交</button></div></div></form></div></div></div></div>
</div>
{% endblock %}

user_MForm_add.html:

{% extends 'layout.html' %}
{% block content %}<div class="container-fluid" style="margin-top: 10px"><div class="my-div"><div class="container"><div class="panel panel-default" style="width: 750px;margin-top: 10px"><!-- Default panel contents --><div class="panel-heading" style="margin-top: 0">新建 用户</div><div class="panel-body"><form class="form-horizontal" method="POST" action="/user/MForm_add/">{% csrf_token %}<!-- 输入框 -->{% for items in form %}<div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">{{ items.label }}</label><div class="col-sm-5">
{#                      <input type="text" class="form-control" id="inputDepartmentName" placeholder="" name="{{ items.label }}">#}{{ items }}
{#                        要是有错误信息,会显示#}<span style="color: red">{{ items.errors.0 }}</span>
{#                        直接手写{{ items }},因为他会自动帮我们生成html标签#}</div></div>
{#                        {{ items.label }} : {{ items }}#}{% endfor %}<!-- 提交按钮 --><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><button type="submit" class="btn btn-primary">提 交</button></div></div></form></div></div></div></div>
</div>{% endblock %}

user_edit.html:

{% extends 'layout.html' %}{% block content %}<div class="container"><div class="panel panel-default" style="width: 750px;margin-top: 10px"><div class="panel-heading" style="margin-top: 0">编辑 用户</div><div class="panel-body"><form class="form-horizontal" method="POST" action="/user/MForm_add/">{% csrf_token %}<!-- 输入框 -->{% for items in form %}<div class="form-group"><label for="inputDepartmentName" class="col-sm-2 control-label">{{ items.label }}</label><div class="col-sm-5">{{ items }}<span style="color: red">{{ items.errors.0 }}</span></div></div>{% endfor %}<!-- 提交按钮 --><div class="form-group"><div class="col-sm-offset-2 col-sm-10"><button type="submit" class="btn btn-primary">提 交</button></div></div></form></div></div></div>
{% endblock %}

感谢您的三连!!!

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

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

相关文章

AIGC视频生成模型:ByteDance的PixelDance模型

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍ByteDance的视频生成模型PixelDance&#xff0c;论文于2023年11月发布&#xff0c;模型上线于2024年9月&#xff0c;同时期上线的模型还有Seaweed&…

深入探究 YOLOv5:从优势到模型导出全方位解析

一、引言 在计算机视觉领域&#xff0c;目标检测是一项至关重要的任务&#xff0c;它在自动驾驶、安防监控、工业检测等众多领域都有着广泛的应用。而 YOLO&#xff08;You Only Look Once&#xff09;系列作为目标检测算法中的佼佼者&#xff0c;一直备受关注。其中&#xff…

Qt —— 控件属性

一、概述 控件有很多属性&#xff0c;我们学习和整理常见和常用的几个属性&#xff0c;由于所有的控件基本都是继承Widget类的&#xff0c;所以前面会先拿Widget类和常见的控件进行示范。 Qt Designer左侧一长条就是Qt给我们内置好的控件&#xff1a; 二、enabled 状态属性 …

会议签到系统的架构和实现

会议签到系统的架构和实现 摘要:通过定制安卓会议机开机APP呈现签到界面&#xff0c;并且通过W/B结构采集管理签到信息&#xff0c;实现会议签到的功能。为达到此目标本文将探讨使用Redis提供后台数据支持&#xff1b;使用SocketIo处理适时消息&#xff1b;使用Flask进行原型开…

WPF实战案例 | C# WPF实现大学选课系统

WPF实战案例 | C# WPF实现大学选课系统 一、设计来源1.1 主界面1.2 登录界面1.3 新增课程界面1.4 修改密码界面 二、效果和源码2.1 界面设计&#xff08;XAML&#xff09;2.2 代码逻辑&#xff08;C#&#xff09; 源码下载更多优质源码分享 作者&#xff1a;xcLeigh 文章地址&a…

JAVA:Spring Boot 实现责任链模式处理订单流程的技术指南

1、简述 在复杂的业务系统中&#xff0c;订单流程往往需要一系列的操作&#xff0c;比如验证订单、检查库存、处理支付、更新订单状态等。责任链模式&#xff08;Chain of Responsibility&#xff09;可以帮助我们将这些处理步骤分开&#xff0c;并且以链式方式处理每一个操作…

stm32单片机个人学习笔记14(USART串口数据包)

前言 本篇文章属于stm32单片机&#xff08;以下简称单片机&#xff09;的学习笔记&#xff0c;来源于B站教学视频。下面是这位up主的视频链接。本文为个人学习笔记&#xff0c;只能做参考&#xff0c;细节方面建议观看视频&#xff0c;肯定受益匪浅。 STM32入门教程-2023版 细…

postgresql15的启动

PostgreSQL是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统&#xff0c;且因为许可证的灵活&#xff0c;任何人都可以以任何目的免费使用、修改和分发PostgreSQL。现在国产数据库大力发展阶段&#xff0c;学习和熟悉postgresql的功能是非常有必要的&#x…

行人识别检测数据集,yolo格式,PASICAL VOC XML,COCO JSON,darknet等格式的标注都支持,准确识别率可达99.5%

作者简介&#xff1a; 高科&#xff0c;先后在 IBM PlatformComputing从事网格计算&#xff0c;淘米网&#xff0c;网易从事游戏服务器开发&#xff0c;拥有丰富的C&#xff0c;go等语言开发经验&#xff0c;mysql&#xff0c;mongo&#xff0c;redis等数据库&#xff0c;设计模…

【前端】CSS实战之音乐播放器

目录 播放器背景旋转音乐封面按钮进度条音量调节音乐信息按钮的效果JavaScript部分播放和暂停音乐切换音乐信息进度条 音量调节避免拖拽时的杂音音量调节条静音和解除静音 自动下一首实现一个小效果最终效果 播放器背景 <div class"play_box"></div>设置…

SSM开发(一)JAVA,javaEE,spring,springmvc,springboot,SSM,SSH等几个概念区别

目录 JAVA 框架 javaEE spring springmvc springboot SSM SSH maven JAVA 一种面向对象、高级编程语言&#xff0c;Python也是高级编程语言&#xff1b;不是框架(框架&#xff1a;一般用于大型复杂需求项目&#xff0c;用于快速开发)具有三大特性&#xff0c;所谓Jav…

rocketmq基本架构

简介 Name server 负责broker注册、心跳&#xff0c;路由等功能&#xff0c;类似Kafka的ZKname server节点之间不互相通信&#xff0c;broker需要和所有name server进行通信。扩容name server需要重启broker&#xff0c;不然broker不会和name server建立连接producer和consum…

【Web】2025-SUCTF个人wp

目录 SU_blog SU_photogallery SU_POP SU_blog 先是注册功能覆盖admin账号 以admin身份登录&#xff0c;拿到读文件的权限 ./article?filearticles/..././..././..././..././..././..././etc/passwd ./article?filearticles/..././..././..././..././..././..././proc/1…

【优选算法】6----查找总价格为目标值的两个商品

这道题相对于前寄到算法题较为容易~ 同样也是使用了双指针的算法哦~ ----------------------------------------begin-------------------------------------- 题目解析&#xff1a; 题目也是很简单地一句话&#xff0c;但是意图还是很明确~ 讲解算法原理&#xff1a; 同样的&…

github登录用的TOTP和恢复码都丢失了怎么办

从22年左右开始github的登录就需要用TOTP的一个6位秘钥做二次认证登录&#xff0c;如果在用的TOTP软件失效了&#xff0c;可以用github开启二次认证时下载的恢复码重置认证&#xff0c;但是如果你和我一样这两个东西都没了就只能用邮箱重置了&#xff0c;过程给大家分享一下 一…

FFmpeg常用命令

文章目录 一、 FFmpeg 音视频的处理流程二、FFmpeg 常用命令2.1、查看本机支持的采集设备2.2、 录制视频2.2.1、原始视频2.2.2、编码的视频 2.3、录制音频&#xff1a;2.3.1、原始音频2.3.2、编码的音频 2.4、录制音视频&#xff1a;2.5、文件格式转换&#xff1a;2.6、提取音频…

30天开发操作系统 第 17 天 -- 命令行窗口

前言 今天一开始&#xff0c;请大家先回忆一下任务A的情形。在harib13e中&#xff0c;任务A下面的LEVEL中有任务因此FIFO为空时我们可以让任务A进入休眠状态。那么&#xff0c;如果我们并未启动任务B0~ B0~ B2, B2的话&#xff0c;任务A又将会如何呢&#xff1f; 首先&#xf…

OpenEuler学习笔记(九):安装 OpenEuler后配置和优化

安装OpenEuler后&#xff0c;可以从系统基础设置、网络配置、性能优化等方面进行配置和优化&#xff0c;以下是具体内容&#xff1a; 系统基础设置 更新系统&#xff1a;以root用户登录系统后&#xff0c;在终端中执行sudo yum update命令&#xff0c;对系统进行更新&#x…

网络安全 | 入侵检测系统(IDS)与入侵防御系统(IPS):如何识别并阻止威胁

网络安全 | 入侵检测系统&#xff08;IDS&#xff09;与入侵防御系统&#xff08;IPS&#xff09;&#xff1a;如何识别并阻止威胁 一、前言二、入侵检测系统&#xff08;IDS&#xff09;2.1 IDS 的工作原理2.2 IDS 的技术类型2.3 IDS 的部署方式 三、入侵防御系统&#xff08;…

数学规划问题2 .有代码(非线性规划模型,最大最小化模型,多目标规划模型)

非线性规划模型 FIrst:转化为标准型 在matlab中求非线性规划的函数 练习题: 典型例题: 最大最小化模型 核心思想&#xff1a; matlab的模型求解 经典例题: 多目标规划模型 基本概念 求解思路: 模型构建步骤 经典例题: 非线性规划模型 非线性规划&#xff08;Nonl…