从零开始搭建Django博客②--Django的服务器内容搭建

本文主要在Ubuntu环境上搭建,为便于研究理解,采用SSH连接在虚拟机里的ubuntu-24.04.2-desktop系统搭建,当涉及一些文件操作部分便于通过桌面化进行理解,通过Nginx代理绑定域名,对外发布。

此为从零开始搭建Django博客系列的第二篇,计划用一周时间完成一个博客搭建并全程记录,便于学习和跟着操作。

从零开始搭建Django博客①–正式开始前的准备工作
从零开始搭建Django博客②–Django的服务器内容搭建

框架理解

我们已经建立了一个基本的名为myblog的Django项目,他的框架如下:

# 项目文件夹结构
├── manage.py  # Django 项目的管理文件
└── myblog  # 项目实际存放目录├── asgi.py  # 运行在 ASGI 兼容的 Web 服务器上的入口├── __init__.py  # 证明该目录此为Python 包。├── settings.py  # Django 项目的配置文件├── urls.py  # Django 项目的 URL 声明,就像你网站的“目录”。└── wsgi.py  # 运行在 WSGI 兼容的Web服务器上的入口

网站构建

在Web应用中,通常有一些业务功能模块是在不同的项目中都可以复用的,故在开发中通常将工程项目拆分为不同的子功能模块,各功能模块间可以保持相对的独立,在其他工程项目中需要用到某个特定功能模块时,可以将该模块代码整体复制过去,达到复用。因此我们每个WEB应用都是有很多不同的子应用组成,在Django中,通过APP来创建子应用。
为了实现一个博客,我们需要以下三种功能:
![[Pasted image 20250422111023.png]]

创建APP

在根目录下通过以下代码创建三个app子应用

# 创建文章功能
python manage.py startapp article
# 创建用户功能
python manage.py startapp user
# 创建评论功能
python manage.py startapp comment

此时项目文件夹结构如下,可以发现其中除了我们建立的三个文件夹,又生成了一个db.sqlit3,这是因为在我们未设置数据库信息时,Djangosettings.py 里默认连接的是项目目录里的该数据库。

![[Pasted image 20250422111427.png]]

连接数据库

为了下一步的数据可视化,我们首先配置数据库信息,打开myblog文件夹目录下的settings.py配置数据库信息:
![[Pasted image 20250422114305.png]]
安装pymysql包(用于连接数据库)和cryptography包(用于处理密码)
settings.py同目录下的__init__.py中导入mysql包相关功能

import pymysql 
pymysql.install_as_MySQLdb()

![[Pasted image 20250422114611.png]]
重新启动Djangond服务器,无报错说明配置无误。

注册APP

同样在 myblog文件夹目录下的settings.py 中,找到INSTALLED_APPS配置项,将新创建的3个app添加到项目的app列表,如下

在这里插入图片描述

创建模型

在此之前,我们先理解DjangoMVT模式

在这里插入图片描述

  • M全拼为Model,负责和数据库交互,进行数据处理。
  • V全拼为View,接收请求,进行业务处理,返回应答。
  • T全拼为Template,负责封装构造要返回的html。

文章模型

数据需求分析

首先分析文章功能需要哪些数据

数据名标题作者创建时间更新时间正文浏览量
idtitleauthorcreatedupdatedbodyviews
类型字符串时间时间大量文本数字
备注外键约束
构建代码
# 文件:article/modle.py
from django.db import models
# 导入django内建的User模型(后面会提)
from django.contrib.auth.models import User
# timezone 用于处理时间相关事务。
from django.utils import timezone
# 用于反向解析,动态生成链接
from django.urls import reverse# 博客文章数据模型
class ArticlePost(models.Model):# 文章标题。models.CharField 为字符串字段,用于保存较短的字符串,比如标题title = models.CharField(max_length=100)# 文章作者。外键约束,参数 on_delete 用于指定数据删除的方式,链接到(User),只要作者(User)被删除,所有该作者的文章数据都会被删除。author = models.ForeignKey(User, on_delete=models.CASCADE)# 文章创建时间。参数 default=timezone.now 指定其在创建数据时将默认写入当前的时间created = models.DateTimeField(default=timezone.now)# 文章更新时间。参数 auto_now=True 指定每次数据更新时自动写入当前时间updated = models.DateTimeField(auto_now=True)# 文章正文。保存大量文本使用 TextFieldbody = models.TextField()# 文章浏览量total_views = models.PositiveIntegerField(default=0)# 内部类 class Meta 用于给 model 定义元数据(Django内部类)class Meta:# ordering 指定模型返回的数据的排列顺序# '-created' 表明数据应该以倒序排列ordering = ('-created',)# 魔术方法 __str__ 定义当调用对象的 str() 方法时的返回值内容。def __str__(self):# return self.title 将文章标题返回return self.title# 获取文章地址,按照数据库id解析为url:/article/iddef get_absolute_url(self):return reverse('article:article_detail', args=[self.id])

评论模型

数据需求分析

首先分析文章功能需要哪些数据

数据名评论文章评论作者评论时间正文
idtitleauthorcreatedbody
类型字符串时间大量文本
备注外键约束
构建代码
from django.db import models
from django.contrib.auth.models import User
from article.models import ArticlePost# 博文的评论
class Comment(models.Model):
# related_name表示可以反向查询文章和用户的评论article = models.ForeignKey(ArticlePost,on_delete=models.CASCADE,related_name='comments')user = models.ForeignKey(User,on_delete=models.CASCADE,related_name='comments')body = models.TextField()created = models.DateTimeField(auto_now_add=True)# 按照创建时间排序class Meta:ordering = ('created',)def __str__(self):return self.body[:20]

数据迁移

编写好了Model后,接下来就需要进行数据迁移。迁移是Django对模型所做的更改传递到数据库中的方式。

注意,每当对数据库进行了更改(添加、修改、删除等)操作,都需要进行数据迁移。

Django的迁移代码是由模型文件自动生成的,它本质上只是个历史记录,Django可以用它来进行数据库的滚动更新,通过这种方式使其能够和当前的模型匹配。

在命令行中输入命令让 Django知道我们自定义模型有一些变更,并根据我们自定义app的模型生成创建数据表的脚本:

python manage.py makemigrations

在这里插入图片描述

python manage.py migrate

在这里插入图片描述

数据查看

可以通过查看数据库检查数据迁移效果

mysql -u 数据库用户名 -p

输入密码后进入数据库

# 切换到数据库
USE 数据库名;
# 显示数据表
SHOW TABLES;

在这里插入图片描述

可以看到数据库中已经有了Django自带的用户数据表和我们创建的文章、评论数据表

创建视图

再看下MVT图:在这里插入图片描述

我们已经构建起Model与数据库之间的联系,下面需要构建模型(Model)与视图(View)之间的关系。
Django 中视图的概念是「一类具有相同功能和模板的网页的集合」。
每一个视图表现为一个简单的Python函数,它需要要做的只有两件事:返回一个包含被请求页面内容的 HttpResponse对象,或者抛出一个异常,比如 Http404
视图函数中的request与网页发来的请求有关,里面包含get或post的内容、用户浏览器、系统等信息。简单来说,视图就是实现将用户的想法通过WEB传递到模型。
根据系统设计过程中需要的功能,我们分别在不同的app 中创建对应的View视图。

文章视图

对于文章,我们需要有以下功能:

  • 文章创建(article_create)
    • 实现文章的创建和提交功能。
  • 文章内容显示(article_detail)
    • 展示文章的标题和内容详情,同时在此视图中取出评论,并展示所有评论列表。
  • 文章删除(article_delete)
    • 实现文章删除功能。
  • 文章修改(article_update)
    • 实现文章的修改功能。
  • 文章排序(article_list)
    • 实现默认按发布日期排序。
    • 实现可按浏览量(热度)排序。
    • 利用Django 的paginator组件实现分页功能。
# 导入Django内部的登录装饰器,可以确保只有登录才能访问相应视图。
from django.contrib.auth.decorators import login_required
# 导入http功能
from django.http import HttpResponse
# 导入render功能和redirect功能
from django.shortcuts import render,redirect
# 导入数据模型ArticlePost
from comment.models import Comment
# 从本目录导入模型
from . import models
# 从本目录的模型中导入文章功能
from .models import ArticlePost
# 引入内置User模型
from django.contrib.auth.models import User
# 引入内置的分页模块
from django.core.paginator import Paginator# 定义文章创建函数
def article_create(request):# 如果用户提交数据,则把相应数据填入变量中if request.method == 'POST':new_article_title = request.POST.get('title')new_article_body = request.POST.get('body')# 默认第一个用户作者new_article_author = User.objects.get(id=1)# 生成一个文章对象,即创建模型。models.ArticlePost.objects.create(title=new_article_title, body=new_article_body,author=new_article_author)return redirect("article:article_list")# 如果用户请求获取数据,则给用户提供一个写文章的界面else:return render(request, 'article/create.html')# 一般都是先请求获取数据--生成写文章界面--写完后再提交数据# 文章详情
def article_detail(request, id):# 取出相应的文章article = ArticlePost.objects.get(id=id)# 浏览量 +1article.total_views += 1# 把新的浏览量字段保存数据库article.save(update_fields=['total_views'])# 取出文章评论comments = Comment.objects.filter(article=id)# 需要传递给模板的对象# context = { 'article': article }context = { 'article': article, 'comments': comments }# 载入模板,并返回context对象return render(request, 'article/detail.html', context)# 删文章
def article_delete(request, id):# 根据 id 获取需要删除的文章article = ArticlePost.objects.get(id=id)# 调用.delete()方法删除文章article.delete()# 完成删除后返回文章列表return redirect("article:article_list")# 更新文章
# 提醒用户登录
@login_required(login_url='/userprofile/login/')
def article_update(request, id):# # 获取需要修改的具体文章对象article = ArticlePost.objects.get(id=id)# 过滤非作者的用户if request.user != article.author:return HttpResponse("抱歉,你无权修改这篇文章。")# 判断用户是否为 POST 提交表单数据if request.method == "POST":new_article_title = request.POST.get('title')new_article_body = request.POST.get('body')article.title = new_article_titlearticle.body = new_article_bodyarticle.save()# 完成后返回到修改后的文章中。需传入文章的 id 值return redirect("article:article_detail", id=id)else:# 赋值上下文,将 article 文章对象也传递进去,以便提取旧的内容context = {'article': article}return render(request, 'article/update.html', context)def article_list(request):# 根据GET请求中查询条件# 如果选择按浏览量排序返回数组if request.GET.get('order') == 'total_views':article_list = ArticlePost.objects.all().order_by('-total_views')order = 'total_views'# 否则按照默认排序返回数组else:article_list = ArticlePost.objects.all()order = 'normal'# 分页,每页4项paginator = Paginator(article_list, 4)# 如果选择了页面page = request.GET.get('page')# 查看该页的文章articles = paginator.get_page(page)# 返回这些文章模型,并按排序返回context = { 'articles': articles, 'order': order }return render(request, 'article/list.html', context)

评论视图

在文件comment/views.py文件中创建如下视图函数,评论比较简单,暂时只创建一个添加评论的就可以了:

# 导入相关模块
from django.shortcuts import render, get_object_or_404, redirect
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse
from article.models import ArticlePost
from . import models# 文章评论
@login_required(login_url='/user/login/')
def post_comment(request, article_id):article = get_object_or_404(ArticlePost, id=article_id)if request.method == 'POST':new_comment_body = request.POST.get('body')new_article_user = request.usermodels.Comment.objects.create(article=article, body=new_comment_body,user=new_article_user)return redirect(article)else:return HttpResponse("发表评论仅接受POST请求。")

用户视图

之所以没创建用户模型是因为Django内置了用户模型,我们在开发一些用户权限控制不复杂的网站或者系统时,可以直接采用Django自带的用户认证模块功能,通过视图调用即可。

用户注册登录

用户注册、登录一般都会用到表单,Django中也内置了一个表单组件,首先我们利用该组件构建表单,在user的app中新建forms.py

# 引入表单类
from django import forms
# 引入 User 模型
from django.contrib.auth.models import User# 登录表单,继承了 forms.Form 类
class UserLoginForm(forms.Form):username = forms.CharField()password = forms.CharField()# 注册用户表单
class UserRegisterForm(forms.ModelForm):# 复写 User 的密码password = forms.CharField()password2 = forms.CharField()class Meta:model = Userfields = ('username', 'email')# 对两次输入的密码是否一致进行检查def clean_password2(self):data = self.cleaned_dataif data.get('password') == data.get('password2'):return data.get('password')else:raise forms.ValidationError("密码输入不一致,请重试。")

以上是一个简单的登录、注册表单实现

视图建设

用户视图需要三个功能,登录(验证账号密码)、退出、注册(新建一条用户数据),代码如下:

from django.shortcuts import render, redirect
from django.contrib.auth import authenticate, login,logout
from django.http import HttpResponse
from .forms import UserLoginForm,UserRegisterForm# Create your views here.
def user_login(request):if request.method == 'POST':user_login_form = UserLoginForm(data=request.POST)if user_login_form.is_valid():# .cleaned_data 清洗出合法数据data = user_login_form.cleaned_data# 检验账号、密码是否正确匹配数据库中的某个用户# 如果均匹配则返回这个 user 对象user = authenticate(username=data['username'], password=data['password'])if user:# 将用户数据保存在 session 中,即实现了登录动作login(request, user)return redirect("article:article_list")else:return HttpResponse("账号或密码输入有误。请重新输入~")else:return HttpResponse("账号或密码输入不合法")elif request.method == 'GET':user_login_form = UserLoginForm()context = { 'form': user_login_form }return render(request, 'userprofile/login.html', context)else:return HttpResponse("请使用GET或POST请求数据")def user_logout(request):logout(request)return redirect("article:article_list")# 用户注册
def user_register(request):if request.method == 'POST':user_register_form = UserRegisterForm(data=request.POST)if user_register_form.is_valid():new_user = user_register_form.save(commit=False)# 设置密码new_user.set_password(user_register_form.cleaned_data['password'])new_user.save()# 保存好数据后立即登录并返回博客列表页面login(request, new_user)return redirect("article:article_list")else:return HttpResponse("注册表单输入有误。请重新输入~")elif request.method == 'GET':user_register_form = UserRegisterForm()context = { 'form': user_register_form }return render(request, 'userprofile/register.html', context)else:return HttpResponse("请使用GET或POST请求数据")

配置路由

定义完视图后,我们需要通过路由访问这些视图:
查找视图的过程 :

  • 1.请求者在浏览器地址栏中输入URL, 请求到网站.
  • 2.网站获取URL信息.
  • 3.然后与编写好的URLconf逐条匹配.
  • 4.如果匹配成功则调用对应的视图.
  • 5.如果所有的URLconf都没有匹配成功.则返回404错误.

在这里插入图片描述

我们有3个app,Django可以对URL进行分级管理,我们在每个app文件夹内的urls.py分别定义各自app相关的URL,然后在根目录DjangoBlog的urls.py中通过include指令来包含各个app中的URL。

  • 需要两步完成URLconf配置
    • 1.在项目中定义URLconf(到应用)
    • 2.在应用中定义URLconf(应用内)

项目中定义路由(根目录的urls.py)

# 引入用户管理后台
from django.contrib import admin
# 记得引入include
from django.urls import path, include
# 需要使用文章视图显示文章列表作为首页
from article import viewsurlpatterns = [path('admin/', admin.site.urls),path('', views.article_list, name='home'),path('article/', include('article.urls', namespace='article')),path('user/', include('user.urls', namespace='user')),path('comment/', include('comment.urls', namespace='comment')),
]

应用中定义路由

文章APP(urls.py)

# 引入path
from django.urls import path
# 引入views.py
from . import views# 正在部署的应用的名称
app_name = 'article'urlpatterns = [path('', views.article_list),# path函数将url映射到视图path('article-list/', views.article_list, name='article_list'),# 文章详情path('article-detail/<int:id>/', views.article_detail, name='article_detail'),# 写文章path('article-create/', views.article_create, name='article_create'),# 删除文章path('article-delete/<int:id>/', views.article_delete, name='article_delete'),# 更新文章path('article-update/<int:id>/', views.article_update, name='article_update'),
]

评论APP(urls.py)

# 引入path
from django.urls import path
# 引入views.py
from . import views# 正在部署的应用的名称
app_name = 'comment'urlpatterns = [# # path函数将url映射到视图# 发表评论path('post-comment/<int:article_id>/', views.post_comment, name='post_comment'),
]

用户APP(urls.py)

from django.urls import path
from . import viewsapp_name = 'user'urlpatterns = [# 用户登录path('login/', views.user_login, name='login'),# 用户退出path('logout/', views.user_logout, name='logout'),# 用户注册path('register/', views.user_register, name='register'),]

至此,所有后端工作准备完毕,下面我们建一个前端模板用于显示相关信息:

创建模板

在根目录新建一个templates文件夹,用于存放模板文件。
配置主要目录下的setting.py中的TEMPLATES,绑定当前创建的templates文件夹地址。
在这里插入图片描述

前期我们已经在视图中设置了视图传入数据的目标地址,以文章视图为例
我们有如下路由和创建文章功能
在这里插入图片描述

在这里插入图片描述

当得到GET请求页面127.0.0.1:8000/article/article-create/时,会调取article_create函数返回 article/create.html 页面.
我们直接用html语言简单建立该页面测试一下:

<!DOCTYPE html>
<html>
<head>
<title>只是测试</title>
</head>
<body>
<div class="container"><div class="row"><div class="col-12"><br><!-- 提交文章的表单 --><form method="post" action="."><!-- Django中需要POST数据的地方都必须有csrf_token -->{% csrf_token %}<!-- 文章标题 --><div class="form-group"><!-- 标签 --><label for="title">文章标题</label><!-- 文本框 --><input type="text" class="form-control" id="title" name="title"></div><!-- 文章正文 --><div class="form-group"><label for="body">文章正文</label><!-- 文本区域 --><textarea type="text" class="form-control" id="body" name="body" rows="12"></textarea></div><!-- 提交按钮,表单提交会直接POST --><button type="submit" class="btn btn-primary">完成</button></form></div></div>
</div>
</body>
</html>

访问127.0.0.1:8000/article/article-create/,得到如下页面:

在这里插入图片描述

到此,我们已经完成了所有应用模型、视图的搭建,并初步构建了一个文件创建的页面进行验证,下一步我们将针对每一个视图建设模板,完成视图与模板之间的连接。

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

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

相关文章

ZLMediaKit支持JT1078实时音视频

ZLMediaKit 对 JT1078 实时音视频协议的支持主要通过其扩展版本或与其他中间件结合实现。以下是基于搜索结果的综合分析&#xff1a; 一、ZLMediaKit 原生支持能力 开源版本的基础支持 ZLMediaKit 开源版本本身未直接集成 JT1078 协议解析模块&#xff0c;但可通过 RTP 推流功能…

Java队列(Queue)核心操作与最佳实践:深入解析与面试指南

文章目录 概述一、Java队列核心实现类对比1. LinkedList2. ArrayDeque3. PriorityQueue 二、核心操作API与时间复杂度三、经典使用场景与最佳实践场景1&#xff1a;BFS层序遍历&#xff08;树/图&#xff09;场景2&#xff1a;滑动窗口最大值&#xff08;单调队列&#xff09; …

MetaGPT智能体框架深度解析:记忆模块设计与应用实践

在AI智能体技术从单点突破迈向系统工程的关键阶段&#xff0c;MetaGPT凭借其创新的记忆架构重新定义了多智能体协作范式。本文深度解构其革命性的三级记忆系统&#xff0c;揭秘支撑10倍效能提升的知识蒸馏算法与动态上下文控制策略&#xff0c;通过企业级应用案例与性能基准测试…

集结号海螺捕鱼服务器调度与房间分配机制详解:六

本篇围绕服务器调度核心逻辑进行剖析&#xff0c;重点讲解用户连接过程、房间分配机制、服务端并发策略及常见性能瓶颈优化。适用于具备中高级 C 后端开发经验的读者&#xff0c;覆盖网络会话池、逻辑服调度器与房间生命周期管理等关键模块。 一、服务器结构概览 整体系统采用…

【电子通识】热敏打印机是怎么形成(打印)图像和文字的?

在我们身边&#xff0c;热敏打印方式常见用于装饰贴纸、便利店的小票。此外&#xff0c;物流及食品条码标签、身份证件、机票・火车票、X光片、食品日期印刷等&#xff0c;很多打印都用到了热敏打印头。 热敏打印头的蓄热层(涂釉层)上分布着一排加热元件&#xff08;发热线&…

SQL注入漏洞中会使用到的函数

目录 一、信息获取函数 1. 通用函数 2. 元数据查询&#xff08;INFORMATION_SCHEMA&#xff09; 二、字符串操作函数 1. 字符串连接 2. 字符串截取 3. 编码/解码 三、报错注入专用函数 1. MySQL 2. SQL Server 3. PostgreSQL 四、时间盲注函数 1. 通用延迟 2. 计…

车载信息安全架构 --- 汽车网络安全

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 周末洗了一个澡,换了一身衣服,出了门却不知道去哪儿,不知道去找谁,漫无目的走着,大概这就是成年人最深的孤独吧! 旧人不知我近况,新人不知我过…

Linux423 删除用户

查找 上面已查过&#xff1a;无法使用sudo 新开个终端试试 之前开了一个终端&#xff0c;按照deepseek排查 计划再开一个进程 开一个终端 后强制删除时显示&#xff1a;此事将被报告

《从卷积核到数字解码:CNN 手写数字识别实战解析》

文章目录 一、手写数字识别的本质与挑战二、使用步骤1.导入torch库以及与视觉相关的torchvision库2.下载datasets自带的手写数字的数据集到本地 三、完整代码展示 一、手写数字识别的本质与挑战 手写数字识别的核心是&#xff1a;从二维像素矩阵中提取具有判别性的特征&#x…

UniOcc:自动驾驶占用预测和预报的统一基准

25年3月来自 UC Riverside、U Wisconsin 和 TAMU 的论文"UniOcc: A Unified Benchmark for Occupancy Forecasting and Prediction in Autonomous Driving"。 UniOcc 是一个全面统一的占用预测基准&#xff08;即基于历史信息预测未来占用&#xff09;和基于摄像头图…

模型量化核心技术解析:从算法原理到工业级实践

一、模型量化为何成为大模型落地刚需&#xff1f; 算力困境&#xff1a;175B参数模型FP32推理需0.5TB内存&#xff0c;超出主流显卡容量 速度瓶颈&#xff1a;FP16推理延迟难以满足实时对话需求&#xff08;如客服场景<200ms&#xff09; 能效挑战&#xff1a;边缘设备运行…

AD9253链路训练

传统方式 参考Xilinx官方文档xapp524。对于AD9253器件 - 125M采样率 - DDR模式&#xff0c;ADC器件的DCO采样时钟(500M Hz)和FCO帧时钟是中心对齐的&#xff0c;适合直接采样。但是DCO时钟不能直接被FPGA内部逻辑使用&#xff0c;需要经过BUFIO和BUFR缓冲后&#xff0c;得到s_b…

解决方案:远程shell连不上Ubuntu服务器

服务器是可以通过VNC登录&#xff0c;排除了是服务器本身故障 检查服务是否在全网卡监听 sudo ss -tlnp | grep sshd确保有一行类似 LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid...,fd3))返回无结果&#xff0c;表明系统里并没有任…

关于大数据的基础知识(四)——大数据的意义与趋势

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于大数据的基础知识&#xff08;四&a…

智能指针(weak_ptr )之三

1. std::weak_ptr 1.1 定义与用法 std::weak_ptr 是一种不拥有对象所有权的智能指针&#xff0c;用于观察但不影响对象的生命周期。主要用于解决 shared_ptr 之间的循环引用问题。 主要特性&#xff1a; 非拥有所有权&#xff1a;不增加引用计数。可从 shared_ptr 生成&…

学习海康VisionMaster之卡尺工具

一&#xff1a;进一步学习了 今天学习下VisionMaster中的卡尺工具&#xff1a;主要用于测量物体的宽度、边缘的特征的位置以及图像中边缘对的位置和间距 二&#xff1a;开始学习 1&#xff1a;什么是卡尺工具&#xff1f; 如果我需要检测芯片的每一个PIN的宽度和坐标&#xff…

Java面试实战:从Spring Boot到微服务的深入探讨

Java面试实战&#xff1a;从Spring Boot到微服务的深入探讨 场景&#xff1a;电商场景的面试之旅 在某互联网大厂的面试间&#xff0c;面试官李老师正襟危坐&#xff0c;而对面坐着的是传说中的“水货程序员”赵大宝。 第一轮&#xff1a;核心Java与构建工具 面试官&#x…

深入理解 Spring @Configuration 注解

在 Spring 框架中,@Configuration 注解是一个非常重要的工具,它用于定义配置类,这些类可以包含 Bean 定义方法。通过使用 @Configuration 和 @Bean 注解,开发者能够以编程方式创建和管理应用程序上下文中的 Bean。本文将详细介绍 @Configuration 注解的作用、如何使用它以及…

密码学中的盐值是什么?

目录 1. 盐值的基本概念 2. 盐值的作用 (1) 防止彩虹表攻击 (2) 防止相同的密码生成相同的哈希值 (3) 增加暴力破解的难度 3. 如何使用盐值&#xff1f; (1) 生成盐值 (2) 将盐值附加到密码 (3) 存储盐值和哈希值 (4) 验证密码 4. 盐值如何增加暴力破解的难度 在线暴…

基于瑞芯微RK3576国产ARM八核2.2GHz A72 工业评估板——Docker容器部署方法说明

前 言 本文适用开发环境: Windows开发环境:Windows 7 64bit、Windows 10 64bit Linux开发环境:VMware16.2.5、Ubuntu22.04.5 64bit U-Boot:U-Boot-2017.09 Kernel:Linux-6.1.115 LinuxSDK:LinuxSDK-[版本号](基于rk3576_linux6.1_release_v1.1.0) Docker是一个开…