当前位置: 首页 > news >正文

Django基础之ORM

一.前言

上一节简单的讲了一下orm,主要还是做个了解,这一节将和大家介绍更加细致的orm,以及他们的用法,到最后再和大家说一下cookie和session,就结束了全部的django基础部分

二.orm的基本操作

1.settings.py,连接数据库

2.settings.py,注册app

3.各app下面的models.py 编写models.类

class UserInfo(models.Model):
    .....
    .....

4.执行命令

python manage.py makemigrations    # 找到所有已注册的app中的models.py中的类读取 -> migrations配置
python manage.py migrate           # 读取已注册的app下的migrations配置 -> SQL语句  -> 同步数据库 

三.连接数据库 

我们django支持各种类型的数据库,例如mysql,sqlite3(默认的)等等,我们连接不同的数据库需要的是改settings.py下面的DATABASES 

1.连接django默认自带的sqlite3

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': BASE_DIR / 'db.sqlite3',
    }
}

2.连接mysql

  • 安装MySQL & 启动MySQL服务

  • 手动创建数据库

  • django的settings.py配置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'xxxxxxxx',  # 数据库名字
        'USER': 'root',
        'PASSWORD': 'root123', #数据库密码
        'HOST': '127.0.0.1',  # ip
        'PORT': 3306,
    }

安装第三方组件(两个选一个,推荐安装pymysql)

  • pymysql

    pip install pymysql
    项目根目录/项目名目录/__init__.pyimport pymysqlpymysql.install_as_MySQLdb()
  • mysqlclient

    pip install mysqlclient
    电脑上先提前安装MySQL。

 四.连接池

django默认内置没有数据库连接池 ,所以我们要使用第三方的。

pip install django-db-connection-pool

DATABASES = {
    "default": {
        'ENGINE': 'dj_db_conn_pool.backends.mysql',
        'NAME': 'day04',  # 数据库名字
        'USER': 'root',
        'PASSWORD': 'root123',
        'HOST': '127.0.0.1',  # ip
        'PORT': 3306,
        'POOL_OPTIONS': {
            'POOL_SIZE': 10,  # 最小
            'MAX_OVERFLOW': 10,  # 在最小的基础上,还可以增加10个,即:最大20个。
            'RECYCLE': 24 * 60 * 60,  # 连接可以被重复用多久,超过会重新创建,-1表示永久。
            'TIMEOUT':30, # 池中没有连接最多等待的时间。
        }
    }

五.多数据库 

多数据库我们平时都用不上,只有在后续开发大项目时才能用得上,大家做个了解就好

DATABASES = {
    "default": {
        'ENGINE': 'dj_db_conn_pool.backends.mysql',
        'NAME': 'day05db',  # 数据库名字
        'USER': 'root',
        'PASSWORD': 'root123',
        'HOST': '127.0.0.1',  # ip
        'PORT': 3306,
        'POOL_OPTIONS': {
            'POOL_SIZE': 10,  # 最小
            'MAX_OVERFLOW': 10,  # 在最小的基础上,还可以增加10个,即:最大20个。
            'RECYCLE': 24 * 60 * 60,  # 连接可以被重复用多久,超过会重新创建,-1表示永久。
            'TIMEOUT': 30,  # 池中没有连接最多等待的时间。
        }
    },
    "bak": {
        'ENGINE': 'dj_db_conn_pool.backends.mysql',
        'NAME': 'day05bak',  # 数据库名字
        'USER': 'root',
        'PASSWORD': 'root123',
        'HOST': '127.0.0.1',  # ip
        'PORT': 3306,
        'POOL_OPTIONS': {
            'POOL_SIZE': 10,  # 最小
            'MAX_OVERFLOW': 10,  # 在最小的基础上,还可以增加10个,即:最大20个。
            'RECYCLE': 24 * 60 * 60,  # 连接可以被重复用多久,超过会重新创建,-1表示永久。
            'TIMEOUT': 30,  # 池中没有连接最多等待的时间。
        }
    },
}

 5.1 读写分离

我们有时候会进行读写分离,这个就需要用到多数据库,我们配置如下

192.168.1.2       default master   [写]
              组件
192.168.2.12      bak slave    [读]

生成数据库表

python manage.py makemigrations    # 找到所有已注册的app中的models.py中的类读取 -> migrations配置

python manage.py migrate
python manage.py migrate --database=default
python manage.py migrate --database=bak

后续再进行开发时

models.UserInfo.objects.using("default").create(title="外交部")
models.UserInfo.objects.using("bak").all() 

我们通过using来选择配置的数据库

我们这里看不见数据是因为读取的数据库我们没有做同步的组件

我们发现我们这样读写分离时每次都要选择指定的数据库,这样很难整,我们可以手动编写router类,让我们每次不需要指定就能知道

编写router类:(两个函数必须叫这个名字)

class DemoRouter(object):def db_for_read(self,model,**hints):return 'settings下面DATABASES的键'def db_for_write(self,model,**hints):return 'settings下面DATABASES的键'

然后我们在settings里面配置一下

DATABASE_ROUTERS=['utils.router.DemoRouter']

这样就是基本的router,然后我们还可以进行更细致的判断

我们说两个常用的对象

model._meta.app_label #app的名字
model._meta.model_name #modelss的名字(全小写)也就是表名

我们也可以基于这个来判断用哪个表

5.2 分库(多app)

也叫多app对应多个数据库

如图我们两个app里有两个model,我们想吧一个app的放在default数据库,另一个app的放在bak数据库,这个时候我们提交的命令就要改,然后就借助我们前面说的router进行判断以此来选择数据库

python manage.py makemigrations

python manage.py migrate 第一个app名字 --database=default

python manage.py migrate 第二个app名字 --database=bak 

....... 

提交好后我们就来开始编辑router

我们现在就通过了一个简单的if判断实现了不同app选择不同数据库的需求了

 5.3 分库(单app)

在一个app中,我们想把多个模型拆分到不同的数据库中就需要,但是此时我们使用命令是无法完成的,我们就需要借助router来编写了

例如这个,我们想把第一张表放在default里面,下面两张表放在bak里面

def allow_migrate(self,db,app_label,model_name=None,**hints):'''执行这个命令的时候python manage.py migrate app名字 --database=defaultapp_label=app名字db=defaultmodel_name 就是models里面的名字(全小写)通过return True 和False判断是否生成'''pass

我们同样还是先执行python manage.py makemigrations 

我们编写好后执行

python manage.py migrate web --database=default

migrate web --database=bak

注意:当我们--database=bak 一定要加上app名字 不然会不成功

六.表关系

这个我们在上一节已经给大家介绍过了(具体的比如参数我就不介绍,这里就直接放代码

一对多:

from django.db import modelsclass Depart(models.Model):title=models.CharField(verbose_name='标题',max_length=32,unique=True)class UserInfo(models.Model):name=models.CharField(verbose_name='姓名',max_length=32,db_index=True)dp=models.ForeignKey(to='Depart',on_delete=models.CASCADE)class Meta:db_table='depart'

这个最后的class Meta下面的db_table='depart'的意思是让在数据库创建的表名为depart,入过不设置的话就是app名字_类名的小写,我们一般都不会设置,因为这样可以避免表名冲突,这里也是给大家引个介绍 

多对多:

from django.db import models
class Boy(models.Model):name = models.CharField(verbose_name='姓名', max_length=32)class Girl(models.Model):name = models.CharField(verbose_name='姓名', max_length=32)class B2G(models.Model):bid=models.ForeignKey(to='Boy',on_delete=models.CASCADE)gid=models.ForeignKey(to='Girl',on_delete=models.CASCADE)

这里我们就不用ManyToManyField这个字段了,上一节也说了

 一对一:

这个是上一节没和大家介绍的,当然肯定有人要问,一对一有啥好用的,为什么不创建一张表呢,但是大家想一想,在有的特殊的场景里面,就拿CSDN来说,我们是不是注册需要名称和密码,但是此时此刻我们还没有开通博客专区,如果我们要开通博客专区,是不是又得创建一张博客表,里面存放我们博客的地址和简介页面,这个时候就会用到一对一

from django.db import models
class UserInfo(models.Model):name=models.CharField(verbose_name='姓名',max_length=32,db_index=True)dp=models.ForeignKey(to='Depart',on_delete=models.CASCADE)class Blog(models.Model):user=models.OneToOneField(to='UserInfo',on_delete=models.CASCADE)blog=models.CharField(verbose_name='博客地址',max_length=128)summery=models.CharField(verbose_name='简介',max_length=255)

七.数据操作 

7.1 单表数据操作

以这个数据库为例:

class Role(models.Model):title=models.CharField(verbose_name='标题',max_length=32)od=models.IntegerField(verbose_name='排序',default=0)

1.创建:

obj1 = models.Role.objects.create(title="管理员", od=1)
obj2 = models.Role.objects.create(**{"title": "管理员", "od": 1})
#通过以上两种直接创建,数据多用下面的那种,数据少用上面的那种,记住下面的字典前面一定要加上**obj = models.Role(title="客户", od=1)
obj.od = 100
obj.save()obj = models.Role(**{"title": "管理员", "od": 1})
obj.od = 100
obj.save()
#这种是先创建对象,放在内存里面,创建完的对象可以修改值,然后.save()就可以提交到数据库

 2.删除:

删除很简单,理论上就是先查找再删除,只要记住找到对象然后再.delete()

models.Role.objects.all().delete()
models.Role.objects.filter(title="管理员").delete()
#第一个是查找全部的对象,第二个filter里面是跟着各种条件,找到以后delete()就行了,他们的返回值是受影响的行数

3.更新

更新和删除的原理都一样,只要记得找到对象然后再update(数据)

models.Role.objects.all().update(od=99)
models.Role.objects.filter(id=7).update(od=99, title="管理员")
models.Role.objects.filter(id=7).update(**{"od": 99, "title": "管理员"})

 4.查找

我们前面删除和更新其实都用到查询了,大家可以发现查询可以查询全部也可以筛选完查询,查询得到的结果类型是QuerySet,里面套着obj类型,很像列表但是不是,我们可以for循环得到里面的每个元素,并且查询得到得返回值还可以.query得到他原本查询得命令

v1 = models.Role.objects.all()
for obj in v1:print(obj, obj.id, obj.title, obj.od)v2 = models.Role.objects.filter(**{"od": 99, "id": 99}) #和前面一样支持两种
for obj in v2:print(obj, obj.id, obj.title, obj.od)v3 = models.Role.objects.filter(id=99)
print(v3.query)v3 = models.Role.objects.filter(id__gt=2)
print(v3.query)v3 = models.Role.objects.filter(id__gte=2)
print(v3.query)v3 = models.Role.objects.filter(id__lt=2)
print(v3.query)v3 = models.Role.objects.filter(id__in=[11, 22, 33])
print(v3.query)v3 = models.Role.objects.filter(title__contains="户")
print(v3.query)v3 = models.Role.objects.filter(title__startswith="户")
print(v3.query)v3 = models.Role.objects.filter(title__isnull=True)
print(v3.query)# 不等于
v3 = models.Role.objects.exclude(id=99)
print(v3.query)#不等于完还能再筛选
v3 = models.Role.objects.exclude(id=99).filter(od=88)
print(v3.query)

大家执行一下然后再看query语句就知道了,我在这里总结一下

全部用.all(),筛选让条件满足用.filter(id=99),筛选让条件取反.exclude(id=99)

__gt= 大于

__gte= 大于等于

__lt=  小于

__lte=  小于等于

__in=[11, 22, 33] 在这个里面

__contains=“户” 包含这个

__startswith="户" 以户开头

__isnull=True 为空

我们上面说的都是QuerySet里面套着obj,但是接下来会讲一些有用的

v4 = models.Role.objects.filter(id__gt=0).values("id", 'title')
print(v4)
v4 = models.Role.objects.filter(id__gt=0).values_list("id", 'title')
print(v4)
v4=models.Role.objects.all().first()
print(v4)
v4 = models.Role.objects.filter(id__gt=0).values("id", 'title').first()
print(v4)
v4 = models.Role.objects.filter(id__gt=10).exists() #判断这个对象是否存在 返回True或者False
print(v4)
# asc
v8 = models.Role.objects.filter(id__gt=0).order_by("id")
print(v8)
# id desc  od asc
v9 = models.Role.objects.filter(id__gt=0).order_by("-id", 'od')
print(v9)

我们所有的都总结一下就是,通过.filter()和.all()拿到的数据就是QuerySet[obj,obj,obj]这种类型的数据。

如果我们想要改变里面的数据类型就可以再在后面加上.value()和.values_list(),不过这里就要加上子弹名字,分别以这些字段构成的字典和元组,只要类型是QuerySet,我们既可以通过.first()拿到QuerySet的第一个元素(无论是对象,字典,元组)。

如果我们想判断QuerySet是否不为空就用.exists()。

如果我们想对拿到的QuerySet里面的元素(无论是对象,字典,元组)进行排序就用.order_by(),里面的参数就是字段名,这就是想升序,字段名前面加了个-就是降序,如果有多个值就是以第一个值为准,如果第一个值一样就按照第二个的来排,理解这些是不是对这些参数运用熟悉多了,所以学习这些还是得先学会数据类型。

7.2 一对多数据操作

class Depart(models.Model):title=models.CharField(verbose_name='标题',max_length=32,unique=True)class UserInfo(models.Model):name=models.CharField(verbose_name='姓名',max_length=32,db_index=True)dp=models.ForeignKey(to='Depart',on_delete=models.CASCADE)

我们一对多以这个数据库为例,当然有很多都是和单表操作是重复的,我这里只和大家说不是重复的部分,也不会和上面讲的那么细

1.创建

models.UserInfo.objects.create(name='往日情怀酿作酒',dp_id=1)obj=models.Depart.objects.filter(id=2).first()
models.UserInfo.objects.create(name='往日情怀酿作酒',dp=obj)
models.UserInfo.objects.create(name='往日情怀酿作酒',dp_id=obj.id)

这里在我们创建ForeignKey关联字段的时候,他在表中的名字会加上_关联字段名字(因为我们上面没有指定to_field,所以默认指定到了id),我们也可以直接用字段,但是后面=的参数就要是个对象了

2.更新

这里我就给大家介绍一个需要注意的点,我们可以通过ForeignKey__标题来实现跨表操作,但是我们更新只能本表数据

models.UserInfo.objects.filter(name="往日情怀酿作酒").update(dp_id=2)#这个是没有问题的
models.UserInfo.objects.filter(id=2).update(dp__title="销售部")#这样是不行的,不能删跨表更改

3.查找

这里不和大家说删除了,是因为主要就是查找,和前面没什么区别,介绍创建主要是为了和大家说一下ForeignKey关联的字段

v1=models.UserInfo.objects.all()
for obj in v1: #但是如果要跨表也就是加上__字段我们通常不会用这个,因为这个效率太差了print(obj.name,obj.id,obj.dp_id) #我们可以通过ForeignKey字段名__另一张表名来跨表v2=models.UserInfo.objects.all().select_related("dp")
for obj in v2: #加上.select_related("depart")相当于把两张表给连起来了,效率就会高很多print(obj.name,obj.id,obj.dp_id)v3=models.UserInfo.objects.all().values('id','name','dp__title')
print(v3)v3 = models.UserInfo.objects.all().values_list('id', 'name', 'dp__title')
print(v3)

我们可以通过ForeignKey字段__来找到跨表的数据,这个是需要关注的

4.重点(容易犯毛病)

#正向操纵
# 我们可以通过ForeignKey进行跨表,这个是没有问题的
v1=models.UserInfo.objects.all().values('id','name','dp_id','dp__title')
print(v1)#反向操作
#django里面会默认把我们用ForeignKey关联的表也可以通过__来连接起来
#例如这个关联了userinfo,那么userinfo也就是代表这个表关联字段的id,userinfo__name代表跨的表名
v2=models.Depart.objects.all().values('id','title','userinfo','userinfo__name')
print(v2)

但是我们假设一下,如果用户表里面有两个ForeignKey,那么他这个表名到底是关联的哪一个ForeignKey字段的id呢?那我们先来更新一下表

我们按照我们需求创建一个新部门new_dp,也是ForeignKey关联的,但是当我们更新表的时候,他会提示报错,这是因为django关联表的时候已经想到反向关联表会出现冲突,这个时候我们就要加上related_name用来做为反向关联的

class UserInfo(models.Model):name=models.CharField(verbose_name='姓名',max_length=32,db_index=True)dp=models.ForeignKey(to='Depart',on_delete=models.CASCADE,related_name='dp1')new_dp=models.ForeignKey(to='Depart',on_delete=models.CASCADE,related_name='dp2',default=1)

 related_name就是当多个ForeignKey关联同一个表时要加上的,到时候我们反向关联就不能用表名了,而是要用related_name

7.3 多对多数据操作 

class Boy(models.Model):name = models.CharField(verbose_name='姓名', max_length=32)class Girl(models.Model):name = models.CharField(verbose_name='姓名', max_length=32)class B2G(models.Model):bid=models.ForeignKey(to='Boy',on_delete=models.CASCADE)gid=models.ForeignKey(to='Girl',on_delete=models.CASCADE)adress=models.CharField(verbose_name='约会地点',max_length=32,default='北京中路八号ma')

 1.创建

models.Boy.objects.create(name="宝强")
models.Boy.objects.create(name="羽凡")
models.Boy.objects.create(name="乃亮")models.Girl.objects.bulk_create(objs=[models.Girl(name="小路"), models.Girl(name="百合"), models.Girl(name="马蓉")],batch_size=3
)models.B2G.objects.create(bid_id=1, gid_id=3, adress="北京")
models.B2G.objects.create(bid_id=1, gid_id=2, adress="上海")
models.B2G.objects.create(bid_id=2, gid_id=2, adress="芜湖")
models.B2G.objects.create(bid_id=2, gid_id=1, adress="安庆")

这里都一样,但是补前面没说的知识点就是批量创建, 用.bulk_create,参数是objs=[],里面是models.表名,不用加上objects,batch_size就是一次提交几个,如果数据多于batch_size那么就第二次创建

2.查找

# 1.宝强都与谁约会。
q = models.B2G.objects.filter(bid__name='宝强').select_related("gid")
for item in q:print(item.id, item.adress, item.bid.name, item.gid.name)# 2.百合 都与谁约会。
q = models.B2G.objects.filter(gid__name='百合').values("id", 'bid__name', 'gid__name')
for item in q:print(item['id'], item['bid__name'], item['gid__name'])

这个没啥特殊的,就举几个例子和大家看看 

7.4 一对一数据操作

一对多大家都会,一对一怎么可能会不会呢?我就不多写了,难打字!

八.cookie和session

8.1 cookie

cookie前面都给大家介绍过了,这里来说一些用到的重要参数

def show(request):res=HttpResponse("返回")res.set_cookie("name",'Mr.7',max_age=100,path='/',domain='www.yy.com',secure=False,httponly=True)return res

max_age:cookie存活时间

path:哪些路径会携带这个cookie

domain:哪些域名会携带这个cookie

secure:是否只在https下携带

httponly:只允许请求使用cookie,这些参数不写也可以

这里要注意一下就是当我们用到域名的时候要在这里加上,通常使用*

8.2 session

session我们通常都是和cookie一起,这样比较方便

用到session我们的这个中间件一定要打开 

文件配置:

SESSION_ENGINE = 'django.contrib.sessions.backends.file'
SESSION_FILE_PATH = 'session'
SESSION_COOKIE_NAME = "sid"  # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
SESSION_COOKIE_PATH = "/"  # Session的cookie保存的路径
SESSION_COOKIE_DOMAIN = None  # Session的cookie保存的域名
SESSION_COOKIE_SECURE = False  # 是否Https传输cookie
SESSION_COOKIE_HTTPONLY = True  # 是否Session的cookie只支持http传输
SESSION_COOKIE_AGE = 1209600  # Session的cookie失效日期(2周)SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期
SESSION_SAVE_EVERY_REQUEST = True  # 是否每次请求都保存Session,默认修改之后才保存

数据库配置:

我们要把这个session的app给打开,并且重新执行makemigrations和migrate让他重新生成session的数据库

# session
SESSION_ENGINE = 'django.contrib.sessions.backends.db'

SESSION_COOKIE_NAME = "sid"  # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
SESSION_COOKIE_PATH = "/"  # Session的cookie保存的路径
SESSION_COOKIE_DOMAIN = None  # Session的cookie保存的域名
SESSION_COOKIE_SECURE = False  # 是否Https传输cookie
SESSION_COOKIE_HTTPONLY = True  # 是否Session的cookie只支持http传输
SESSION_COOKIE_AGE = 1209600  # Session的cookie失效日期(2周)

SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期
SESSION_SAVE_EVERY_REQUEST = True  # 是否每次请求都保存Session,默认修改之后才保存

缓存版:

我们首先要创建缓存,这里介绍用redis,首先要安装模块

pip install django-redis

再在settings.py里面创建 CACHES

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100}
            # "PASSWORD": "密码",
        }
    }

# session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default' 

SESSION_COOKIE_NAME = "sid"  # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串
SESSION_COOKIE_PATH = "/"  # Session的cookie保存的路径
SESSION_COOKIE_DOMAIN = None  # Session的cookie保存的域名
SESSION_COOKIE_SECURE = False  # 是否Https传输cookie
SESSION_COOKIE_HTTPONLY = True  # 是否Session的cookie只支持http传输
SESSION_COOKIE_AGE = 1209600  # Session的cookie失效日期(2周)

SESSION_EXPIRE_AT_BROWSER_CLOSE = False  # 是否关闭浏览器使得Session过期
SESSION_SAVE_EVERY_REQUEST = True  # 是否每次请求都保存Session,默认修改之后才保存

九.总结 

今天的内容有很多,主要就是麻烦,大家后期肯定会大量的用到,毕竟是最重要的,所以内容多也很正常,我感觉主要还是得先理解数据类型,这样就会更好理解

十.补充 

下一期将和大家开始讲项目,期待大家的点赞关注加收藏 

相关文章:

Django基础之ORM

一.前言 上一节简单的讲了一下orm,主要还是做个了解,这一节将和大家介绍更加细致的orm,以及他们的用法,到最后再和大家说一下cookie和session,就结束了全部的django基础部分 二.orm的基本操作 1.settings.py&#x…...

【以音频软件FFmpeg为例】通过Python脚本将软件路径添加到Windows系统环境变量中的实现与原理分析

在Windows系统中,你可以通过修改环境变量 PATH 来使得 ffmpeg.exe 可在任意路径下直接使用。要通过Python修改环境变量并立即生效,如图: 你可以使用以下代码: import os import winreg as reg# ffmpeg.exe的路径 ffmpeg_path …...

检测到联想鼠标自动调出运行窗口,鼠标自己作为键盘操作

联想鼠标会自动时不时的调用“运行”窗口 然后鼠标自己作为键盘输入 然后打开这个网页 (不是点击了什么鼠标外加按键,这个鼠标除了左右和中间滚轮,没有其他按键了)...

web UI自动化测试笔记

在当今数字化转型的浪潮中,Web 应用已经无处不在,而其质量保障的关键之一就是自动化测试。想象一下,如果每次都手动验证 UI 功能,不仅耗时耗力,还容易遗漏问题。Python 的强大生态为 Web UI 自动化测试提供了高效的解决…...

计算机网络 (60)蜂窝移动通信网

一、定义与原理 蜂窝移动通信网是指将一个服务区分为若干蜂窝状相邻小区并采用频率空间复用技术的移动通信网。其原理在于,将移动通信服务区划分成许多以正六边形为基本几何图形的覆盖区域,称为蜂窝小区。每个小区设置一个基站,负责本小区内移…...

计算机网络三张表(ARP表、MAC表、路由表)总结

参考: 网络三张表:ARP表, MAC表, 路由表,实现你的网络自由!!_mac表、arp表、路由表-CSDN博客 网络中的三张表:ARP表、MAC表、路由表 首先要明确一件事,如果一个主机要发送数据,那么必…...

DRF开发避坑指南01

在当今快速发展的Web开发领域,Django REST Framework(DRF)以其强大的功能和灵活性成为了众多开发者的首选。然而,错误的使用方法不仅会导致项目进度延误,还可能影响性能和安全性。本文将从我个人本身遇到的相关坑来给大…...

批量提取多个 Excel 文件内指定单元格的数据

这篇文章将介绍如何从多个相同格式的Excel文件中,批量提取指定单元格的数据,合并后保存到新的工作薄。 全程0代码,可视化操作。 提取前: 提取后: 准备数据 这里准备了3个测试数据 开始提取 打开的卢易表&#xff0…...

#HarmonyOS篇:build-profile.json5里面配置productsoh-package.json5里面dependencies依赖引入

oh-package.json5 用于描述包名、版本、入口文件和依赖项等信息。 {"license": "","devDependencies": {},"author": "","name": "entry","description": "Please describe the basic…...

Spring集成Redis|通用Redis工具类

一、基础使用 概述 在SpringBoot中一般使用RedisTemplate提供的方法来操作Redis。那么使用SpringBoot整合Redis需要 那些步骤呢。 1、 JedisPoolConfig (这个是配置连接池) 2、 RedisConnectionFactory 这个是配置连接信息,这里的RedisConnectionFactory是一个接 …...

Vue中设置报错页面和“Uncaught runtime errors”弹窗关闭

文章目录 前言操作步骤大纲1.使用Vue自带的报错捕获机制添加报错信息2.在接口报错部分添加相同机制3.把报错信息添加到Vuex中方便全局使用4.添加报错页面备用5.app页面添加if判断替换报错界面 效果备注:vue项目中Uncaught runtime errors:怎样关闭 前言 在开发Vue项…...

【力扣】219. 存在重复元素 II

题目 给你一个整数数组 nums 和一个整数 k &#xff0c;判断数组中是否存在两个 不同的索引 i 和 j &#xff0c;满足 nums[i] nums[j] 且 abs(i - j) < k 。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a…...

头歌实训作业 算法设计与分析-贪心算法(第5关:求解流水作业调度问题)

问题描述 有 n 个作业&#xff08;编号为1&#xff5e;n&#xff09;要在由两台机器 M 1和 M 2 组成的流水线上完成加工。每个作业加工的顺序都是先在 M 1​上加工&#xff0c;然后在 M 2 上加工。 M 1 和 M 2 加工作业 i 所需的时间分别为 a i 和 b i&#xff08;1≤i≤n&am…...

Hadoop•搭建完全分布式集群

听说这里是目录哦 一、安装Hadoop&#x1f955;二、配置Hadoop系统环境变量&#x1f96e;三、验证Hadoop系统环境变量是否配置成功&#x1f9c1;四、修改Hadoop配置文件&#x1f36d;五、分发Hadoop安装目录&#x1f9cb;六、分发系统环境变量文件&#x1f368;七、格式化HDFS文…...

SQL-leetcode—1141. 查询近30天活跃用户数

1141. 查询近30天活跃用户数 表&#xff1a;Activity ---------------------- | Column Name | Type | ---------------------- | user_id | int | | session_id | int | | activity_date | date | | activity_type | enum | ---------------------- 该表没有包含重复数据。 …...

总结与展望,龙蜥社区第 30 次运营委员会会议线上召开

2025 年 1 月 20 日&#xff0c;龙蜥社区召开了第 30 次运营委员会线上会议&#xff0c;来自 24 家理事单位的 22 位委员及委员代表出席&#xff0c;本次会议由运营委员凝思软件李晨斌主持。会上总结和回顾了龙蜥社区 1 月运营发展情况&#xff0c;同步了龙蜥社区 3 大运营目标…...

idea对jar包内容进行反编译

1.先安装一下这个插件java Bytecode Decompiler 2.找到这个插件的路径&#xff0c;在idea的plugins下面的lib文件夹内&#xff1a;java-decompiler.jar。下面是我自己本地的插件路径&#xff0c;以作参考&#xff1a; D:\dev\utils\idea\IntelliJ IDEA 2020.1.3\plugins\java-d…...

c++----------------------多态

1.多态 1.1多态的概念 多态(polymorphism)的概念&#xff1a;通俗来说&#xff0c;就是多种形态。多态分为编译时多态(静态多态)和运⾏时多 态(动态多态)&#xff0c;这⾥我们重点讲运⾏时多态&#xff0c;编译时多态(静态多态)和运⾏时多态(动态多态)。编译时 多态(静态多态)…...

C语言 指针_野指针 指针运算

野指针&#xff1a; 概念&#xff1a;野指针就是指针指向的位置是不可知的&#xff08;随机的、不正确的、没有明确限制的&#xff09; 指针非法访问&#xff1a; int main() {int* p;//p没有初始化&#xff0c;就意味着没有明确的指向//一个局部变量不初始化&#xff0c;放…...

【JavaEE进阶】Spring留言板实现

目录 &#x1f38d;预期结果 &#x1f340;前端代码 &#x1f384;约定前后端交互接口 &#x1f6a9;需求分析 &#x1f6a9;接口定义 &#x1f333;实现服务器端代码 &#x1f6a9;lombok介绍 &#x1f6a9;代码实现 &#x1f334;运行测试 &#x1f384;前端代码实…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

反射获取方法和属性

Java反射获取方法 在Java中&#xff0c;反射&#xff08;Reflection&#xff09;是一种强大的机制&#xff0c;允许程序在运行时访问和操作类的内部属性和方法。通过反射&#xff0c;可以动态地创建对象、调用方法、改变属性值&#xff0c;这在很多Java框架中如Spring和Hiberna…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...