Django项目之订单管理part1
一.前言
我们前面把django的常用知识点给讲完了,现在我们开始项目部分,项目是一个订单管理系统,我们同时也会在项目之中也会讲一些前面没有用到的知识点。
项目大概流程如下:

核心的功能模块:
-
认证模块,用户名密码 或 手机短信登录(60s有效)。
-
角色管理,不同角色具有不同权限 和 展示不同菜单。
管理员,充值客户,下单
-
客户管理,除了基本的增删改查以外,支持对客户可以分级,不同级别后续下单折扣不同。
-
交易中心
-
管理员可以给客户余额充值/扣费
-
客户可以下单/撤单
-
生成交易记录
-
对订单进行多维度搜索,例如:客户姓名、订单号。
-
-
worker,去执行订单并更新订单状态。
二.单点知识
2.1 群发短信
这个需要我们去开通腾讯云短信服务,具体大家浏览器搜索就知道了,参考下面:
短信 Python SDK-SDK 文档-文档中心-腾讯云https://cloud.tencent.com/document/product/382/43196https://cloud.tencent.com/document/product/382/43196https://cloud.tencent.com/document/product/382/43196https://cloud.tencent.com/document/product/382/43196
https://cloud.tencent.com/document/product/382/43196
大概精简下来就长这样
# -*- coding: utf-8 -*-
from tencentcloud.common import credential
from tencentcloud.sms.v20210111 import sms_client, models# SecretId和SecretKey
cred = credential.Credential("SecretId", "SecretKey")
client = sms_client.SmsClient(cred, "ap-guangzhou")req = models.SendSmsRequest()# 设置的appid
req.SmsSdkAppId = "appid"
# 设置的签名内容
req.SignName = "签名内容"
# 模板id
req.TemplateId = "模板id"
# 验证码内容
req.TemplateParamSet = ["666666"]
req.PhoneNumberSet = ["+8615888888888"]
resp = client.SendSms(req)print(resp)
2.2 权限和菜单管理
2.2.1 菜单
不同的用户登陆时会看到不同的菜单,那我们此时此刻就有几种选择方式,一是写到html的母版里面,但是这样的弊端就是后续更改页面位置太多会比较麻烦,我们也可以把菜单的设计放在settings里面或者数据库里面。
页面写死 HTML模板:
<html>
{% if 角色 "管理员"%}
<a href="/xxx/x">用户管理</a>
<a href="/xxx/x">级别管理</a>
<a href="/xxx/x">级别管理</a>
...
{% else %}
<a href="/xxx/x">xxx管理</a>
<a href="/xxx/x">级别管理</a>
{% endif %}
</html>
将菜单放在配置文件中:
# settings.py
ADMIN = [
{"title":"用户管理", "url":"...." },
{"title":"用户管理", "url":"...." },
{"title":"用户管理", "url":"...." },
{"title":"用户管理", "url":"...." },
]USER = [
{"title":"用户管理", "url":"...." },
{"title":"用户管理", "url":"...." },
{"title":"用户管理", "url":"...." },
{"title":"用户管理", "url":"...." },
]
<html>
{% if 角色 "管理员"%}
{% for item in ADMIN%}
<a href="{{item.url}}">{{item.title}}</a>
{%emdfor%}
{% else %}
{% for item in USER%}
<a href="{{item.url}}">{{item.title}}</a>
{%emdfor%}
{% endif %}
</html>
将 菜单+角色 写入数据库 :
| id | title | url |
|---|---|---|
| 1 | 用户管理 | ... |
| 2 | 级别管理 | ... |
| 3 | 订单管理 | ... |
| id | 角色 |
|---|---|
| 1 | 管理员 |
| 2 | 用户 |
| id | role_id | menu_id |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 2 |
在页面展示数据库 1.查询特定角色关联的所有的菜单 2.在页面上进行展示
如果选择使用配置文件的方式:
ADMIN = [
{
"title":"用户管理",
"children":[
{"title":"级别列表","url":"....", "name":"level_list",}
{"title":"级别列表","url":"...."}
{"title":"级别列表","url":"...."}
]
},
{
"title":"订单管理",
"children":[
{"title":"订单列表","url":"...."}
{"title":"订单列表","url":"...."}
{"title":"订单列表","url":"...."}
]
},
]
这个name是我们可以通过name反向生成ur,在前面路由里面和大家说过
菜单选中和展开问题:
1.获取当前用户请求的 URL pricepolicy/list/ 或 url对应的name
2. pricepolicy/list/ 配置 ADMIN中的URL ->默认选中
路径导航的问题 :
1.获取当前用户请求的 URL pricepolicy/list/ 或 url对应的name
2.获取上级,展示导航信息
3.设置菜单与下级关系
扩展:菜单多级关系
| id | title | url | parent_id |
|---|---|---|---|
| 1 | 客户管理 | null | null |
| 2 | 级别列表 | ... | 1 |
| 3 | 客户列表 | ... | 1 |
| 4 | 订单管理 | null | null |
| 5 | 价格 | ... | 4 |
| 6 | 交易 | ... | 4 |
| 7 | 其他 | ... | 6 |
注意:类似与平台的评论。
| id | content | root_id | parent_id | depth |
|---|---|---|---|---|
| 1 | 优秀 | null | null | 0 |
| 2 | 不咋样 | null | null | 0 |
| 3 | 确实 | 1 | 1 | 1 |
| 4 | 哈哈 | 1 | 1 | 1 |
| 5 | 你说的都对 | 1 | 3 | 2 |
- 优秀
确实
你说的都对
哈哈
- 不咋样
2.2.2 权限
我们在权限的判断时,应该要两种判断,一种是客户点击页面,一种是导航条输入api,都要进行判断,我们一般就是把客户和他对应的url存放到字典或者集合,每次访问都在中间件进行判断,不用列表是因为列表的查询效率特别的低特别的耽误时间
文件settings.py的方式:
admin_permisions = {
"level_list":{...},
"level_edit":{..., 'parent':'level_list'},
"level_add":{... 'parent':'level_list'},
"level_delete":{..'parent':'level_list'.},
"user_list":{...},
"user_edit":{...},
"user_add":{...},
"user_delete":{...},
}user_permisions = {
...
}
当然我们通常不会存储链接,而是存储name和naspace
admin访问某个URL + 路由信息(name、namespace),获取当前的URL /level/edit/4/ -> 是否存在URL,因为有的url是可变的,比如编辑删除,他的客户信息都是动态的
在中间件中根据URL中的name进行权限的校验。
数据库方式:

2.3 队列

-
rabbitMQ,Linux命令+服务构建+python代码。
-
kafka,Linux命令+服务构建+python代码。
-
redis的列表

基于redis实现上述的过程和代码示例:
-
安装redis
-
启动redis
这里我就不说安装教程了,大家不记得直接去搜就好了
Python操作redis:
pip install redis
import redisconn = redis.Redis(host='127.0.0.1', port=6379, encoding='utf-8')
# 短信验证码
conn.set('15131255089', 9999, ex=10)
value = conn.get('15131255089')
print(value)
import redisconn = redis.Redis(host='127.0.0.1', port=6379, encoding='utf-8')# 放值
# conn.lpush('my_queue', "root")
# conn.lpush('my_queue', "good")# 取值
v1 = conn.brpop("my_queue", timeout=5)
print(v1)
这是两种实例代码,上面是我们用来短信验证码的,而下面就是我们的任务队列
2.4 worker和线程池
# 1.去redis中获取任务
import time
# 2.再将此订单在数据库中的状态修改为 执行中# 3.获取任务详细:100个任务# 4.线程池或协程
from concurrent.futures import ThreadPoolExecutordef task(arg):# 执行任务# 模拟运行时间time.sleep(1)start_time=time.time()
pool = ThreadPoolExecutor(50)
for i in range(100):pool.submit(task, "任务参数")pool.shutdown() # 卡主,等待所有的任务执行完毕。
end_time=time.time()
# 5.更新订单状态,已完成
print(end_time-start_time)
这个就是前面说的多线程
三.项目
我们这里完整的说一下整个项目的创建,不记得的可以看前面几篇,有更具体的介绍
1.我们新创建一个项目django_project,然后安装django3.2
2.执行命令django-admin startproject django_project .
3.这里我们只创建一个app,我们就叫web,执行命令python manage.py startapp web
4.连接数据库,pip install pymysql,再在项目同名的文件夹下的__init__.py写入
import pymysql pymysql.install_as_MySQLdb() 然后再在settings改成mysql的配置5.屏蔽掉settings里面没用的组件,让项目是一个纯净版的django(可不做)
6.再将app注册
3.1 表结构设计
表结构设计我们要有管理员表,客户表,级别表(折扣等级),价格表,订单表,交易记录表。
这里我就直接给代码了,代码也都给上注释了
from django.db import modelsclass ActiveBaseModel(models.Model):"""用来继承的表"""active = models.SmallIntegerField(verbose_name='状态', default=1,choices=((1, '激活'), (0, '删除'))) # 用来进行逻辑删除而不是物理删除class Meta:abstract = True # 把 ActiveBaseModel 设置为抽象类,防止在数据库中创建表class Administrator(ActiveBaseModel):"""管理员表"""username = models.CharField(verbose_name='用户名', max_length=32, db_index=True)password = models.CharField(verbose_name='密码', max_length=64)mobile = models.CharField(verbose_name='手机号', max_length=11, db_index=True)create_date = models.DateTimeField(verbose_name='创建日期',auto_now_add=True) # auto_now_add和之前说的auto_now的区别是前者只在创建的时候自动生成,后者在后面更新的时候也会自动更新,我们这里要的是第一次创建的class Level(ActiveBaseModel):"""级别表"""title = models.CharField(verbose_name='标题', max_length=32)percent = models.IntegerField(verbose_name='折扣')class Customer(ActiveBaseModel):"""客户表"""username = models.CharField(verbose_name='用户名', max_length=32, db_index=True)password = models.CharField(verbose_name='密码', max_length=64)mobile = models.CharField(verbose_name='手机号', max_length=11, db_index=True)balance = models.DecimalField(verbose_name='账户余额', default=0, max_digits=10, decimal_places=2)level = models.ForeignKey(verbose_name='级别', to='Level', on_delete=models.CASCADE)creator = models.ForeignKey(verbose_name='创建者', to='Administrator', on_delete=models.CASCADE)create_date = models.DateTimeField(verbose_name='创建日期', auto_now_add=True)class PricePolicy(models.Model):"""价格策略 (原价,后续可以根据级别享受不同折扣)1000 52000 8"""count = models.IntegerField(verbose_name="数量")price = models.DecimalField(verbose_name='价格', default=0, max_digits=10, decimal_places=2)class Order(ActiveBaseModel):"""订单表"""status_choices = ((1, '待执行'),(2, '正在执行'),(3, '已完成'),(4, '失败'),)status = models.SmallIntegerField(verbose_name='状态', choices=status_choices, default=1)oid = models.CharField(verbose_name='订单号', max_length=64, unique=True)count = models.IntegerField(verbose_name='数量')price = models.DecimalField(verbose_name='价格', default=0, max_digits=10,decimal_places=2) # 价格这里我们不通过价格策略关联,因为如果我们后期更换价格策略,会对不上账real_price = models.DecimalField(verbose_name='实际价格', default=0, max_digits=10, decimal_places=2)old_view_count = models.CharField(verbose_name="原播放量", max_length=32,default="0") # 不用整型是因为我们拿到的播放量很容易是字符串例如1.2wcreate_date = models.DateTimeField(verbose_name='创建日期', auto_now_add=True)customer = models.ForeignKey(verbose_name='客户', to="Customer", on_delete=models.CASCADE)memo = models.TextField(verbose_name='备注', null=True, blank=True)class TransactionRecord(ActiveBaseModel):"""交易记录"""charge_type_class_mapping = {1: 'success',2: 'danger',3: 'default',4: 'info',5: 'primary',}#这个是根据bootstrap的按钮样式来做的一个字典charge_type_choices=((1,"充值"),(2,"扣款"),(3,"创建订单"),(4,"删除订单"),(5,"撤单"),)charge_type=models.SmallIntegerField(verbose_name="类型",choices=charge_type_choices)customer=models.ForeignKey(verbose_name='客户',to='Customer',on_delete=models.CASCADE)amount=models.DecimalField(verbose_name='金额',default=0,max_digits=10,decimal_places=2)creator=models.ForeignKey(verbose_name='管理员',to='Administrator',on_delete=models.CASCADE,null=True,blank=True)order_oid=models.CharField(verbose_name='订单号',max_length=64,null=True,blank=True,db_index=True)
这里就是表结构的代码,大家可以看看
3.2 用户认证相关
-
用户名和密码登录
-
短信登录
-
页面展示
-
提交数据
-
根据数据去数据库校验
-
通过,登录成功 session
-
失败,页面展示错误信
-
登录成功后,保存用户的信息session【文件、数据库、缓存中】
而今天最后的最后就是来写用户登录的代码
3.2.1 基本页面

我们先创建一个templates存放html,因为我们后面要写的视图函数比较多,所以我们就把views.py删掉换成 一个文件夹,文件夹里面放入给类视图函数,因为我们现在要做登录相关函数所以我们先创建一个account.py。

我们先写一个简单的登录页面,这里给大家介绍几个需要注意的点,第一个就是如果是post请求(ajax除外),就一定要加上这个csrf_token (不然就会报错),或者把中间件里的csrf关掉
{% csrf_token %}

3.2.2 bootstrap优化页面
但是我们发现这个样式有点丑,我们可以借用bootstrap进行美化,我们先去下载,然后在app目录下面创建static文件夹,然后再创建文件,把下载好的bootstrap引入进去,然后再引入到html里面

这样就是创建好了,我们就要开始写好看的页面了,这里不过多叙述,我们就借助ai和bootstrap来写一个稍微能看的页面就行了,这里直接给出代码
login.html
{% load static %}<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="{% static '/plugins/bootstrap/css/bootstrap.css' %}"><style>.box {width: 400px;border: 1px solid #dddddd;margin-left: auto;margin-right: auto;margin-top: 200px;padding-left: 40px;padding-right: 40px;padding-bottom: 30px;box-shadow: 5px 10px 10px rgb(0 0 0 /5%);}</style></head>
<body><div class="box"><h2 style="text-align: center">用户登录</h2><form method="post" action="{% url 'login' %}" class="form-horizontal">{% csrf_token %}<div class="form-group"><label>角色</label><select name="role" class="form-control"><option value="2">客户</option><option value="1">管理员</option></select></div><div class="form-group"><label>用户名</label><input type="text" class="form-control" id="exampleInputPassword1" name="username" placeholder="用户名"></div><div class="form-group"><label>密码</label><input type="password" class="form-control" id="exampleInputPassword1" name="password" placeholder="密码"></div><div class="form-group"><div class="checkbox"><label><input type="checkbox"> 记住我</label></div></div><div class="form-group"><button type="submit" class="btn btn-primary">登录</button><a href="{% url 'sms_login' %}" style="float: right">短信登录</a></div></form></div><h1></h1></body>
</html>
sms_login.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="{% static '/plugins/bootstrap/css/bootstrap.css' %}"><style>.box {width: 400px;border: 1px solid #dddddd;margin-left: auto;margin-right: auto;margin-top: 200px;padding-left: 40px;padding-right: 40px;padding-bottom: 30px;box-shadow: 5px 10px 10px rgb(0 0 0 /5%);}</style>
</head>
<body><div class="box"><h2 style="text-align: center">短信登录</h2><form method="post" action="{% url 'sms_login' %}" class="form-horizontal">{% csrf_token %}<div class="form-group"><label>角色</label><select name="role" class="form-control"><option value="2">客户</option><option value="1">管理员</option></select></div><div class="form-group"><label>手机号</label><input type="text" class="form-control" id="inputEmail3" name="mobile" placeholder="手机号"></div><div class="form-group"><label>短信验证码</label><div class="row"><div></div><div class="col-md-9"><input type="password" class="form-control" id="inputPassword3" name="code"placeholder="短信验证码"></div><div class="col-md-3"><input type="button" value="发送短信" class="btn btn-default"></div></div></div><div class="form-group"><button type="submit" class="btn btn-primary">登录</button><a href="{% url 'login' %}" style="float: right">用户名登录</a></div></form></div></body>
</html>

优化后的页面虽然不好看,但是也能看
3.2.3 登录逻辑
我们现在就要来写登录逻辑了,我们在写登录逻辑之前肯定知道,如果登录成功肯定要存储到session,我们上节说过session配置缓存,那我们就要按照上节配置一下。

我们创建数据库存放密码的时候,通常用的是密文,那我们就创建一个utils文件夹来存放加密解密
这个seetings.SECRET_KEY是django创建项目的时候生成的,我们把这个充当是盐

这样我们一个简单的登录逻辑就写好了,那我们就要开始测试了,我们平时都是直接在数据库里面写入数据,但是这个密码是md5还要加上盐,我们手动创建会很麻烦,我们可以写一点离线脚本
import os
import sys
import djangobase_dir=os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(base_dir)
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '项目名.settings')
django.setup()from web import models
from utils.encrypt import md5models.Administrator.objects.create(username='admin',password=md5('admin'),mobile='18888888888')
我们通过这个就能写django的离线脚本了,通过脚本给数据库添加点东西,或者还可以在项目终端执行python manage.py shell,然后写入代码,但是这个直接一次性执行,不是很方便
3.2.4 form表单验证
我们现在想想,我们这个是不是什么都不输入并且密码错误以后什么都没有了,此时我们就要借助form,这样可以解决这一点
from django.shortcuts import render,redirect
from web import models
from utils.encrypt import md5
from django import formsclass LoginForm(forms.Form):role=forms.ChoiceField(required=True,choices=(('2','客户'),('1','管理员')),widget=forms.Select(attrs={'class':'form-control'}))username=forms.CharField(required=True,widget=forms.TextInput(attrs={'class':'form-control','placeholder':'用户名'}))password=forms.CharField(required=True,widget=forms.PasswordInput(attrs={'class':'form-control','placeholder':'密码'})) #密码默认不保留 如果想要保留就加上render_value=Truedef login(request):if request.method=="GET":form=LoginForm()return render(request,'login.html',{'form':form})#通过form来校验form=LoginForm(request.POST)if not form.is_valid():#这个来开始校验return render(request,'login.html',{'form':form}) #这个相当于是把上一次的值写进去# 验证成功之后 form.cleaned_data就是存放的所有数据username=form.cleaned_data.get('username')password=form.cleaned_data.get('password')password=md5(password) #我们存放到数据库要用md5role=form.cleaned_data.get('role')mapping={'1':'ADMIN','2':'CUSTOMER'}if role not in mapping:return render(request,'login.html',{'form':form,'error':'角色不存在'})if role=='1':user_object=models.Administrator.objects.filter(active=1,username=username,password=password).first() #因为是逻辑删除,所以一定要加上active=1else:user_object = models.Customer.objects.filter(active=1, username=username, password=password).first()# 校验失败if not user_object:return render(request, 'login.html', {'form':form,'error': '用户名或密码错误'})# 校验成功存到session+进入项目后台request.session['user_info']={'role':mapping[role],'name':user_object.username,'id':user_object.id}return redirect('/home/')
我直接上代码,也都加上了注释,但是我在这里把重要的点加上来给你说,下重点
1.定义form必须要继承forms.Form
2.最开始定义例如:username=forms.CharField(),括号里面加上一些字段,如果要带上标签的类型的话要加上widget=forms.TextInput() 或者别的标签,根据标签来,要加上的类型例如class,就写上attrs={},这样子,其中name不用写,name就默认等于定义的名字,如username
3.form=LoginForm(request.POST) 这个就是把requests.POST的值放进去一个个比对
4.form.is_valid() 来判断是否比对成功
5.比对成功之后form.cleaned_data就是一个字典,里面存放所有要的数据
最新的login.html
{% load static %}<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><link rel="stylesheet" href="{% static '/plugins/bootstrap/css/bootstrap.css' %}"><style>.box {width: 400px;border: 1px solid #dddddd;margin-left: auto;margin-right: auto;margin-top: 200px;padding-left: 40px;padding-right: 40px;padding-bottom: 30px;box-shadow: 5px 10px 10px rgb(0 0 0 /5%);}@keyframes fadeOut {0% {opacity: 1;}99% {opacity: 1;}100% {opacity: 0;visibility: hidden;}}</style></head>
<body><div class="box"><h2 style="text-align: center">用户登录</h2><form method="post" action="{% url 'login' %}" class="form-horizontal" >{% csrf_token %}<div class="form-group"><label>角色</label>{{ form.role }}</div><div class="form-group"><label>用户名</label>{{ form.username }}</div><div class="form-group"><label>密码</label>{{ form.password }}</div><div class="form-group"><div class="checkbox"><label><input type="checkbox"> 记住我</label></div></div><div class="form-group"><button type="submit" class="btn btn-primary">登录</button><span style="animation: fadeOut 2s forwards;color: red">{{ error }}</span><a href="{% url 'sms_login' %}" style="float: right">短信登录</a></div></form></div></body>
</html>
四.总结
今天说的内容有点多,刚开始嘛都这,我也写了好久了,主要的还是form表单的验证,下一期将更加完善这个项目,会涉及ajax,短信登陆等等
五.补充
下一期将和大家开始讲项目,期待大家的点赞关注加收藏
相关文章:
Django项目之订单管理part1
一.前言 我们前面把django的常用知识点给讲完了,现在我们开始项目部分,项目是一个订单管理系统,我们同时也会在项目之中也会讲一些前面没有用到的知识点。 项目大概流程如下: 核心的功能模块: 认证模块,用…...
Electron通过ffi-napi调用dll导出接口
electron使用ffi-napi环境搭建 附打包好的ffi-napi可以直接放到项目目录下使用,避免以后麻烦 一、安装node.js Node.js官网:https://nodejs.org/zh-cn/download,选择LTS长期稳定版本即可 ,但不会是nil。 string is the set of all strings of 8-bit bytes, conventionally but not nec…...
前端笔试面试资源汇总
好的,我现在需要帮助用户找到热门实用的前端笔试面试贴。首先,回顾之前的对话,用户已经询问了常见的前端算法题目,现在他们想要更广泛的资源,可能包括面试题、面经、学习资料等。用户可能正在准备前端面试,…...
win11安装wsl报错:无法解析服务器的名称或地址(启用wsl2)
1. 启用wsl报错如下 # 查看可安装的 wsl --install wsl --list --online此原因是因为没有开启DNS的原因,所以需要我们手动开启DNS。 2. 按照如下配置即可 Google的DNS(8.8.8.8和8.8.4.4) 全国通用DNS地址 (114.114.114.114) 3. 运行以下命令来重启 WSL…...
【Day44 LeetCode】图论问题 Ⅱ
一、图论问题 Ⅱ 1、岛屿的最大面积 这题和上一篇博客求岛屿数量如出一辙,都是要找出所有岛屿,深度优先搜索代码如下: # include<iostream> # include<vector>using namespace std;int dfs(vector<vector<int>> …...
技术总结 | MySQL面试知识点
存储引擎 Mysql 中的存储引擎 查询存储引擎的命令 show engines; Archive 只支持 insert 与select操作, 不支持索引 不支持事务 适用于存储需要长期保存,但是很少访问的数据,例如 历史日志 BlackHole 不存储数据,但是会记录写入操作 适用于性能测试 语言验证等情况 MyISAM…...
frameworks 之 Activity添加View
frameworks 之 Activity添加View 1 LaunchActivityItem1.1 Activity 创建1.2 PhoneWindow 创建1.3 DecorView 创建 2 ResumeActivityItem 讲解 Activity加载View的时机和流程 涉及到的类如下 frameworks/base/core/java/android/app/Activity.javaframeworks/base/services/cor…...
Linux下Ollama下载安装速度过慢的解决方法
问题描述:在Linux下使用默认安装指令安装Ollama,下载安装速度过慢,进度条进度缓慢,一直处于Downloading Linux amd64 bundle中,具体如下图所示: 其中,默认的Ollama Linux端安装指令如下…...
【小白学HTML5】一文讲清常用单位(px、em、rem、%、vw、vh)
html5中,常用的单位有px、em、rem、%、vw、vh(不常用)、cm、m等,这里主要讲解px、em、rem、%、vw。 学习了解:主流浏览器默认的字号:font-size:16px,无论用什么单位,浏览器最终计算…...
用自定义注解实现Excel数据导入中的枚举值校验
使用自定义注解实现Excel数据导入中的枚举值校验 在实际开发中,我们经常需要从Excel文件中导入数据,并且这些数据需要符合一定的规则,比如某些字段的值必须是预定义的枚举值。本文将介绍如何使用自定义注解来实现这一功能,以提高…...
关于redis的主从复制(下)
目录 全量复制 关于replid和runid 部分复制 补充问题 实时复制 psync可以从主节点获取全量数据,也可以获取一部分数据。主要就是看offset的进度,如果offset写作-1,就是获取全量数据。offset写具体的正整数,则是从当前偏移量位…...
uniapp uni.request重复请求处理
类似这种切换tab时,如果操作很快并且网络不太好,就出现数据错乱,在网上查了一圈,有一个使用uview拦截处理的,但是原生uni.requse没有找到详细的解决办法,就查到使用 abort 方法,我自己封装了一个…...
【大模型】DeepSeek:AI浪潮中的破局者
【大模型】DeepSeek:AI浪潮中的破局者 引言:AI 新时代的弄潮儿DeepSeek:横空出世展锋芒(一)诞生背景与发展历程(二)全球影响力初显 探秘 DeepSeek 的技术内核(一)独特的模…...
SOME/IP--协议英文原文讲解8
前言 SOME/IP协议越来越多的用于汽车电子行业中,关于协议详细完全的中文资料却没有,所以我将结合工作经验并对照英文原版协议做一系列的文章。基本分三大块: 1. SOME/IP协议讲解 2. SOME/IP-SD协议讲解 3. python/C举例调试讲解 4.2 Speci…...
用PyInstaller构建动态脚本执行器:嵌入式Python解释器与模块打包 - 简明教程
技术场景: 需分发的Python工具要求终端用户可动态修改执行逻辑将Python环境与指定库(如NumPy/Pandas)嵌入可执行文件实现"一次打包,动态扩展"的轻量化解决方案。 ▌ 架构设计原理 1. 双模运行时识别 # 核心判断逻辑…...
在做题中学习(89):螺旋矩阵
解法:模拟 思路:创建ret数组,用变量标记原矩阵的行数和列数,遍历一个元素就push_back进ret数组,每次遍历完一行或一列,相应行/列数--,进行顺时针螺旋遍历到为0即可。 细节:要有边界…...
从零搭建微服务项目Base(第5章——SpringBoot项目LogBack日志配置+Feign使用)
前言: 本章主要在原有项目上添加了日志配置,对SpringBoot默认的logback的配置进行了自定义修改,并详细阐述了xml文件配置要点(只对日志配置感兴趣的小伙伴可选择直接跳到第三节),并使用Feign代替原有RestT…...
数据结构《图》
数据结构《图论》 图的性质 一、无向图(Undirected Graph) 定义 由一组顶点(Vertex)和一组无向边(Edge)构成。 每条无向边用一条无方向的线段连接两个顶点,记为 ( (u, v) ),其中…...
【数据分析】通过个体和遗址层面的遗传相关性网络分析
禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍原理应用场景加载R包数据下载函数个体层面的遗传相关性网络分析导入数据数据预处理构建遗传相关性的个体网络对个体网络Nij进行可视化评估和选择最佳模型评估和选择最佳模型最佳模型…...
在 macOS 的 ARM 架构上按住 Command (⌘) + Shift + .(点)。这将暂时显示隐藏文件和文件夹。
在 macOS 的 ARM 架构(如 M1/M2 系列的 Mac)上,设置 Finder(访达)来显示隐藏文件夹的步骤如下: 使用快捷键临时显示隐藏文件: 在Finder中按住 Command (⌘) Shift .(点ÿ…...
【产品经理】需求分析方法论+实践
阐述了需求分析的基本认知,包括需求分析的定义、原则和内容。接着,文章详细介绍了需求分析的十个步骤,从收集需求到结果评审,为产品经理提供了清晰的操作指南。 作为产品经理,需求分析是一个最基本的工作,但…...
Windows平台的小工具,功能实用!
今天给大家分享一款超实用的Windows平台监控工具,堪称“桌面小管家”,能帮你轻松掌握电脑的各种运行状态,比如网速、下载速度、内存和CPU占用率等常用参数,让你的电脑运行情况一目了然。 TrafficMonitor 网速监控悬浮窗软件 这款…...
意图识别概述
在当今的人工智能领域,意图识别技术是自然语言处理(NLP)中的一个重要分支,它使得机器能够理解人类语言背后的目的或意图。对于鸿蒙操作系统而言,掌握意图识别技术可以极大地提升用户体验,使设备能更好地响应…...
54. c++类型转换
c是强类型语言,它有自己的类型系统,隐式类型转换是在类型转换时,自动转换且数据不丢失,显示类型转换是指定转换类型;在c风格的类型转换中 ,如下代码进行转换 #include <iostream>int main(int argc,…...
SAP-工单技术性关闭操作手册
文章目录 单个工单批量处理TECO和CLSD标识的区别 单个工单 事务代码CO02,输入工单号后回车 功能-》限制处理-》技术性完成 工单状态更改 撤销TECO操作 CO02输入工单号,功能-》限制处理-》撤销技术性完成 批量处理 事务代码COHV,点击生…...
