Django-开放静态资源-获取请求携带的数据-pychram连接数据库-修改Django默认数据库-DjangoORM操作--表管理-记录管理-01
目录
django项目就类似于一所大学,各个app 就相当于二级学院
以登录功能为例走一个django项目(今日内容 引子)
关于静态资源访问
你可能会发现,在我们目前的 django 项目中的 html 模板中链入的 css 、js (这里只服务器本地的,CDN等除外)明明路径是对的,请求得到的却是 404 资源不存在
为什么要配置静态文件才能获取静态资源
用户可以访问的资源,都在 url 中
只有 url 中开设(配置)相关的资源你才能访问到(不然就可以根据路径把网站源码都拿过去了)
后端资源一般都需要手动指定是否需要暴露给用户
配置完之后也只有输入完整的文件路径才能访问到(也相对是一种保护措施)
对于前端已经写好了的文件,我们只是拿过来使用,那么这些文件都可以称之为 “静态文件”
html文件默认全部放在 templates 文件夹下(并且,如果是命令行创建的项目,并不会自带 templates 文件夹,自己创建的就需要去配置文件里配置)
常见的静态文件种类
css
js
iamge (图片)
bootstrap、fontawesome等前端框架,已经写好了的
bootstrap-3.3.7-dist,bootstrap 是依赖于 jquery的,所以在导bootstrap 之前要先导入 jquery
如何配置来开启访问权限
默认的 django 项目 是没有 static 这个文件的,需要自己手动创建 static 文件夹,然后需要去 settings.py 文件配置 static 静态资源相关
# ... 差不多在 settings.py 文件的最下面
STATIC_URL = '/static/' # 接口前缀(跟请求路径相关)
# 只要你想访问静态文件中的资源,路径就必须以 /static/ 开头
# STATIC_URL = '/xxx/' # 引用静态文件资源的地方要改成 /xxx/....
# 下面这个是要手动配置的,手动将所有的静态资源文件暴露给用户
STATICFILES_DIRS = [ # 跟实际文件的查找位置相关
# 这里可以配置很多个,就类似于操作系统环境变量的查找,依次去文件夹里找
os.path.join(BASE_DIR, "static"), # 真正的文件夹路径
]
创建完 static文件夹后,一般还会再在里面手动创建三个文件夹
- css 放当前网站所有的 样式 文件(自己写的)
- js 放当前网站所有的 js 文件(自己写的)
- image 放当前网站所有的 图片 文件
禁用浏览器缓存
写 django 项目最好禁用掉浏览器缓存,不然可能写的代码页面上缓存看不到效果、变化(资源加载地址等等)
要开着 F12开发者工具查看 *****
django的自动重启机制(热启动)
实时监测文件代码变化,只要有变化,就会自动重启,可能代码还没有写完就会自动报错(如果有语法错误可能不会自动重启,遇到逻辑错误就会重启)
静态文件接口动态解析
如果你的产品经理要让你上1000个静态资源的前缀改了,再改回来,总之就是改来改去,怎么办?
备注:这个一般是结合 static 静态文件配置来用的
使用静态文件接口动态解析
...html代码(这一块一般在 head 标签里引用)
{% load static %} <-- 开启静态文件接口动态解析 -->
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
<script src="{% static 'bootstrap-3.3.7-dist/js/bootstrap.min.js' %}"></script>
...html代码
向服务器发送数据
利用 form 表单默认的 get 请求携带
form 表单提交方式默认是 get 请求,携带数据的方式是 url 问号后面跟数据(浏览器地址栏直接拼接也是一样的,本质都是发送一个请求过去,数据都封装成了请求的数据格式)
?username=jason&password=123
form 表单改用 post 请求提交数据
- 把html模版中 form 表单的 method 改成 post(method=‘post’)
- 去 settings.py 里 把 CSRF 这个中间件禁用掉
回顾:action提交地址的三种写法
- 不写的情况下 默认往当前地址提交(url)
- 还可以写后缀/index/ (django项目常用这种)
- 还可以写全路径
代码区分请求方式
request.method
能够获取前端请求方式(并且是全大写的字符串 POST、GET)
def test_request_way(request):
print(request.method, type(request.method))
# GET <class 'str'> # 直接浏览器敲 http://127.0.0.1:8000/test_request_way/ 的方绘制
return HttpResponse('alallala')
推荐写法
可以根据这个来判断请求方式,对于不同的请求方式作出不同的处理
def del_user(request):
if request. method == 'POST':
# post 请求的逻辑处理
return HttpResponse('这是一个 POST 请求!')
# get 请求的逻辑处理(如果是 post,上面就已经return 了,不会执行到这里)
return HttpResponse('这是一个 GET 请求!')
获取请求带过来的数据
WSGI帮忙封装了 request 等,也经过了 Django后端,才有了request 这个对象(请求相关内容 全在 environ 里面)
GET、POST
request.POST
获取前端表单 POST 提交的所有数据(就类似于一个大字典)
取数据
request.POST.get('username') # 虽然value是一一个列表但是默认只取列表最后一个元素
password = request.POST['password'] # --->强烈不建议你使用中括号的形式取值,不存在会直接报错
# 如果想直接把列表全部拿出来 --> request.POST.getlist('hobby') # 获取用户爱好、下拉框的选项
request.GET
获取前端 GET 提交的所有数据(就类似于一个大字典)
取数据
request.GET.get('username') # 虽然value是一一个列表但是默认只取列表最后一个元素
# 如果没有 get 请求携带的数据,就是一个空字典
password = request.GET['password'] # --->强烈不建议你使用中括号的形式取值,不存在会直接报错
# 如果想直接把列表全部拿出来 --> request.GET.getlist('hobby') # 获取用户爱好、下拉框的选项
pycharm 图形化工具连接数据库
准备工作,安装插件
然后安装一下插件( downloads...)
配置连接信息
一定要注意选择那个 MySQL for 5.1(mysql 版本不高的时候),就两个选项反正不行换一个试试嘛
不然 Test Connection 可能会报错
图形页面基本操作
不是重点,鼠标悬浮上去都有提示,自己看吧。。。
过滤多余的字符编码之类的?
不显示数据表?
修改 django 项目配置(应用mysql)
django 默认使用的是自带的 sqlite 数据库(一种小型的做测试用的数据库)
要让 django 项目应用其他数据库(mysql),需要做如下两步配置
在 settings.py 里面配置数据库连接信息
配置的时候 key 必须全大写
... 省略一堆 配置信息
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql', # 直接把原来的 sqlite3 改成 mysql
# mysql 相关配置信息
'HOST': '127.0.0.1',
'PORT': 3306,
'USER': 'root',
'PASSWORD': '000000',
'NAME': 'day51', # 数据库名
'CHARSET': 'utf8'
}
}
... 其他配置信息
指定数据库“软件”?
在项目名下的 __init__.py
文件或者是应用名文件下的 __init__.py
文件下加入一段代码(指定使用的数据库软件?)
django 默认用 MySQLdb 连数据库的(需要自己引入,MySQLdb 比较老了,兼容性也不太好,所以要自己指定)
import pymysql
pymysql.install_as_MySQLdb() # 把 pymysql 装成 MySQLdb 或者 取别名成 MySQLdb ?
django ORM
跟之前 手撸ORM 核心思路一样,只不过这个更加强大而已(强大不知道多少倍去了)
关系映射:
表 ---> 类
一条条记录 ---> 对象
字段对应的值 ---> 对象的属性
在models.py 里创表模型类
django 会默认给你的表创建一个名为 id 的主键字段,所以可以不写这个 id 主键
但如果不是名为 id (是 s_id) 那还是得自己写,一旦你已经指定了主键字段 那么 django 就不会主动再给你创建了
注意点
- CharField 必须指定 max_length 参数,不指定会报错
- 字段修改的注意点(下面有展开介绍)
- 其他注意点 ...
app01/models.py
from django.db import models
# Create your models here.
class User(models.Model):
# 将id字段设置为User表主键字段 在django orm中 你可以不写主键字典 django会默认给你的表创建一个名为id的主键字段
# id = models.AutoField(primary_key=True) # 一旦你自己指定了主键字段 那么django就不会自动再帮你创建了
username = models.CharField(max_length=32) # username varchar(32) CharField必须要指定max_length参数
# password = models.IntegerField() # password int
password = models.CharField(max_length=64)
# addr = models.CharField(max_length=32,default='China') # default该字段默认值
# age = models.IntegerField(null=True) # 该字段允许为空
def __str__(self): # 重写了对象的 __str__ 方法,这样后面打印对象的时候就是这个字符串了
return '我是user表中的对象:%s' % self.username
创建表、修改表--数据库迁移命令(同步到数据库)
python3 manage.py makemigrations
记录数据库迁移
仅仅是在 migrations 文件夹中 记录数据库的修改,并不会直接操作数据库
在当前 app 的 migration 文件夹下会多出一个 .py 文件(记录数据库更改)
python3 manage.py migrate
将数据库修改记录(migrations 中的记录)真正同步到数据库
要等一会儿(第一次执行数据库迁移(还是同步啊?没试)命令会自动创建一堆表(django需要依赖的表),后续就是更新多出来的这几张表的记录了)
简便写法
这里写会有提示,但还是要会自己完整写, 万一面试让手写呢?
makemigrations
记录数据库迁移
会产生类似如下的文件
app01/migrations/0008_auto_20190916_2358.py
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2019-09-16 23:58
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('app01', '0007_remove_user_addr'),
]
operations = [
migrations.AlterField(
model_name='user',
name='password',
field=models.IntegerField(),
),
]
首次创建表时(写模型类时)
app01/migrations/0001_initial.py
# -*- coding: utf-8 -*-
# Generated by Django 1.11.11 on 2019-09-16 04:29
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='User',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('username', models.CharField(max_length=32)),
('password', models.IntegerField()),
],
),
]
migrate
同步到数据库
新增或者更新新出的那些 表的记录
注意
只要动了models 中跟数据库相关的代码,就必须重新执行上面的两条命令,缺一不可
特殊点--表名会自动加上模块的前缀
自动加前缀,可以方便协同开发,解耦合,合在一起就行了(那大家都创 app01 呢?)
表字段的增删改
改完后必须执行数据库迁移的那两条命令
而且一般也不会让你去动表结构,表是在开发之前就要定下来的!
增加表字段
当表里已经有记录时,后续还要想添加字段,需要指定默认值 或者 允许新增字段为空
1.给新增的字段设置默认值
addr = models.CharField(max_length=32,default='China') # default该字段默认值
2.给新增的字段设置成可以为空
age = models.IntegerField(null=True) # 该字段允许为空
当没有记录 或者 表还未被创建时,则不会有上述问题
删除表字段
- 直接在表模型类里 加注释 / 删除
- 重新执行两条命令即可
强调!:执行完之后,表中该字段所对应的所有数据全部清空
---》 没事儿别瞎注释!或者删除(这不仅仅是python代码,还牵连着数据库)
并且一般也不会真正意义上的删除(除非设计不合理)
改字段
结合新增字段和删除字段(小推测,未实践)
数据的增删改查(ORM)
导入 models 里面的表
查数据(跟前面手动封装的一样)
from app01 import models # ORM操作需要使用 models 类中的名字
查记录
get(拿到一个对象,对象没有会报错,不推荐)
models.User.objects.get(username=username, 条件2)
filter(拿到列表,可以放多个参数(条件))
models.User.objects.filter(username=username, password=password, 条件3)
返回的是一个列表(QuerySet),里面放的才是一个个的对象
当查询条件不存在时,不会报错,只会返回一个空列表
filter 括号内支持写多个参数,并且参数之间是 and 关系
print(res.query)
可以打印查询语句(只有 QuerySet 对象才可以直接查看内部对应的 sql 语句) orm 暂时做个了解,后面有详解QuerySet 对象你可以把它当成列表操作,索引也可以用索引取,但是不推荐这么做( QuerySet 只支持整数索引,不支持负数) 还支持切片操作(也不支持负数,切出来的结果还是一个 QuerySet 对象)
QuerySet 封装的方法(个别)
..... filter().first() 拿列表中的第一个对象
空列表不会报错
不推荐你使用索引取值,一旦没有任何数据,再索引取值会报错,但是如果用 .first()
虽然内部也是按索引取值,但是没有数据, 也不会报错,返回的是None
models.User.objects.filter(username=username).first()
少了 .first() 会报这个错
all (拿到所有的)
models.User.objects.all()
直接拿到 User 表模型类的所有数据,结果是列表套对象
增加记录
新增对象的两种方式
create 方法
models.User.objects.create(username=username, password=password)
create方法能够新增数据并且有一个返回值
返回值就是新增的数据对象本身
实例化对象调用 .save()
...省略一堆代码
user_obj = models.User(username=username, password=password)
user_obj.save()
...省略一堆代码
删除记录
models.User.objects.filter(条件).delete()
html中利用 a 标签的 href 把参数发过去(加一个删除功能)
models.User.objects.filter(条件).delete()
更新记录
无论是什么请求,request.GET 都能拿到 url 里携带的参数
总体思路
先传过来id
获取记录 重定向到页面让用户修改
获取用户提交过来的新信息,更新数据,重定向到列表页
.filter(条件).update(username=username, password=password) 批量更新
models.User.objects.filter(id=edit_id).update(username=username,password=password)
.filter 拿到的是一个列表,所以 .filter
的操作 都是批量操作(如果 .filter 结果列表中有多个数据,那么会一次性全部修改,就类似于 for循环一个个修改)
直接 对象.改属性 .save保存
edit_obj.username = username
edit_obj.password = password
edit_obj.save()
不推荐!--> 会从头到尾将所有的字段修改一遍(遍历身上的属性),效率极低
用户信息增删改查
先通过 orm 展示所有的数据到前端
all() 拿所有数据
模板语法 for 循环
添加新增按钮,能够实现用户的新增操作
利用 a 标签的 href 直接触发后端的逻辑
添加编辑、删除按钮
编辑
删除
利用 get 请求携带参数的特点,在url的后面跟上对应数据的id值
request.GET.get()
如果是编辑
重新渲染一个页面,将编辑对象传递到前端,让用户修改
如果是删除
直接利用 filter(条件).delete()
重定向定位不同的页面
与ORM相关的代码实现
app01/views.py
from django.shortcuts import render, HttpResponse, redirect
from app01 import models
# Create your views here.
def login(request):
# 视图函数针对不同的请求方式 应该有不同的处理逻辑
# if request.method == 'GET':
# print('收到了')
# print(request.method) # 能够获取前端请求方式 并且是全大写的字符串
# print(type(request.method))
# return render(request,'login.html')
# elif request.method == 'POST':
# # 获取用户输入 做相应的逻辑判断
# return HttpResponse("拿到了 老弟")
if request.method == 'POST':
print(request.POST) # 获取前端post请求提交过来的数据 就把它当成一个大字典即可
# <QueryDict: {'username': ['jason', 'zekai'], 'password': ['123']}>
username = request.POST.get('username') # 默认取列表最后一个元素
# password = request.POST['password'] # 不推荐 使用
password = request.POST.get('password')
# hobby = request.POST.getlist('hobby')
# print(username,password,hobby)
# print(type(username),type(password),type(hobby))
# 利用orm从数据库获取数据 校验
# 1.查询数据
# 1.1 get()
# user_obj = models.User.objects.get(username=username) # select * from user where username='jason'
# """
# get方法 能够直接拿到数据对象本身 但是 当查询条件不存在的时候 会直接报错 所有不推荐使用
# """
# print(user_obj)
# print(user_obj.username)
# print(user_obj.password)
# 1.2 filter()
# res = models.User.objects.filter(username=username,password=password)
"""
filter查询出来的结果是一个"列表 列表内放的才是一个个的数据对象本身"
当查询条件不存在的时候 不会报错 只会返回一个空列表
filter括号内 支持写多个参数 并且参数与参数之间是and的关系
"""
# print(res.query) # 只有querySet对象才可以直接点query查看年内部对应的sql语句
# 1.filter拿到的结果就是一个querySet对象(你现在只需要知道filter拿到的结果就能够点query查看sql语句)
"""
SELECT `app01_user`.`id`, `app01_user`.`username`, `app01_user`.`password`
FROM `app01_user`
WHERE (`app01_user`.`username` = jason AND `app01_user`.`password` = 123)
"""
# print(res)
# user_obj = res[0:2]
"""
querySet对象 你可以吧它当做列表操作 取值也可以通过索引取(querySet只支持正数索引 不支持负数) 还支持切片操作(切出来的结果还是一个querySet对象)
但是不推荐你这么做
"""
user_obj = models.User.objects.filter(username=username).first() # 拿列表中第一个数据对象
"""
不推荐你使用索引取值 原因在于一旦没有任何数据 再索引取值会报错
但是如果用first虽然内部也是按照索引取值 但是没有数据 也不会报错 返回的是None
"""
# print(user_obj,user_obj.username,user_obj.password)
if user_obj:
if user_obj.password == password:
return redirect('http://www.xiaohuar.com')
return HttpResponse('用户不存在 ')
print(request.GET) # 如果没有get请求携带的数据 就是一个空字典
print(request.GET.get('username'))
print(request.GET.getlist('hobby'))
return render(request, 'login.html')
"""
http://127.0.0.1:8000/static/bootstrap-3.3.7-dist/css/bootstrap.min.css
"""
def reg(request):
if request.method == 'POST':
username = request.POST.get("username")
password = request.POST.get('password')
# orm插入数据
# 1.create()
# res = models.User.objects.create(username=username,password=password) # insert into user(username,password) values(username,password)
# """
# create方法能够新增数据 并且有一个返回值
# 返回值就是新增的数据对象本身
# """
# print(res)
# print(res.username)
# print(res.password)
# 2.利用对象
user_obj = models.User(username=username, password=password)
user_obj.save()
return render(request, 'reg.html')
def user_list(request):
# 将user表中的数据全部查出
data = models.User.objects.all() # select * from user
"""
拿到的也是一个querySet对象
"""
print(data.query)
return render(request, 'userlist.html', {'user_list': data})
def del_user(request):
# 根据用户想要删除的数据的id值 取数据库中删除数据
# 获取到id值
delete_id = request.GET.get('id')
# 拿着id去数据库中删除
models.User.objects.filter(id=delete_id).delete() # delete from user where id = delete_id;
return redirect('/userlist/')
def update_user(request):
# 编辑 是基于已经存在了的数据 进行一个修改
# 逻辑:获取用户想要修改的数据的主键值 然后去数据库修改数据
edit_id = request.GET.get('id')
# 给用户将数据查出来 展示到页面上 让用户自己修改
edit_obj = models.User.objects.filter(id=edit_id).first()
# 将编辑对象传递给前端页面
if request.method == 'POST':
# 不要关系思维 post请求中也是获取get请求携带的参数
username = request.POST.get('username')
password = request.POST.get('password')
# 更新数据
# 方式1:
# models.User.objects.filter(id=edit_id).update(username=username,password=password)
# update user set username = username,password = password where id = edit_id
"""
filter拿到是一个列表 filter操作其实都是批量操作
如果filter结果列表中有多个数据 那么会一次性全部修改
类似于for循环一个个修改
"""
# 方式二(不推荐使用)
edit_obj.username = username
edit_obj.password = password
edit_obj.save()
"""
第二种方式会从头到尾将所有的字段全部修改一遍 效率极低
"""
return redirect('/userlist/')
return render(request, 'update_user.html', {"edit_obj": edit_obj})
def test_request_way(request):
print(request.method, type(request.method))
# GET <class 'str'>
return HttpResponse('alallala')
代码书写位置--个人小总结(待补充)
--> 暨 django 目录结构再解读
为了防止后期搞混,不知道代码往哪写,所以最好还是把,每个文件写在哪的搞清楚(app 里面还是项目同名文件夹下?)
app文件下的
views.py 视图函数/类 一般都是分应用(某个方面)来对应功能(视图函数)的
models.py 数据库模型类,一般还会给模型类加上app的前缀(django设计的是可以分开开发,最后合并,故这里这样做能保证数据表名不重复(那app名字一样呢...))
项目同名文件下的
urls.py 路由配置
settings.py django暴露给用户可以配置的配置信息,这里包含了 app 注册、templates 路径配置、static 静态资源路径配置等
app 和 项目同名目录 都可以放的
单独拎出来可能记得更深点吧
__init__.py 前面指定数据库软件的
import pymysql
pymysql.install_as_MySQLdb()
项目根目录的
static 静态资源文件夹,要记得改配置(settings.py、html引入的时候用static文件路径动态解析)
templates 模版文件夹,要记得配置(settings.py)
大多通过 manage.py 执行 django 的命令
--> 这个文件专门用来读取命令行命令,并作出处理
Django-开放静态资源-获取请求携带的数据-pychram连接数据库-修改Django默认数据库-DjangoORM操作--表管理-记录管理-01的更多相关文章
- zzy:请求静态资源和请求动态资源, src再次请求服务器资源
[总结可以发起请求的阶段:请求动态资源:通过web.xml匹配action然后,自定义Servlet处理该action1)form表单提交请求的时候,用action设定,该页面发起请求的Servlet ...
- Django的静态资源
如果你的静态资源是某个APP专属,那么就在这个APP目录下建立一个static目录,就像上图report这个APP中的static目录.当浏览这个APP的网页时它会从这里去找资源,当然,它首先会从共用 ...
- django 访问静态资源
urlpatterns = patterns('', url(r'^$', views.show, name='index'), url(r'^static/(?P<path>.*)', ...
- 解决Django项目静态资源无法访问的问题
静态资源无法访问 url.py中配置 from django.conf.urls import url from django.views import static from django.conf ...
- django中静态资源
创建静态资源存放路径,为了设置静态媒体,你需要设立存储它们的目录.在你的项目目录(例如/myproject/),创建叫做static的目录.在static里再创建一个images目录和js目录 设置项 ...
- django搭建一个小型的服务器运维网站-查看和修改服务器配置与数据库的路由
目录 项目介绍和源码: 拿来即用的bootstrap模板: 服务器SSH服务配置与python中paramiko的使用: 用户登陆与session; 最简单的实践之修改服务器时间: 查看和修改服务器配 ...
- Node.js——开放静态资源原生写法
借助了mime第三方包,根据请求地址请求的文件后缀,设置content-type
- [Java][Web]Request 获取请求头和数据
获取方式一 InputStream in = request.getInputStream(); int len = 0; byte buffer[] = new byte[1024]; while( ...
- [Django框架 - 静态文件配置、request对象方法初识、 pycharm链接数据库、ORM实操增删改查、django请求生命周期]
[Django框架 - 静态文件配置.request对象方法初识. pycharm链接数据库.ORM实操增删改查.django请求生命周期] 我们将html文件默认都放在templates文件夹下 将 ...
随机推荐
- Oracle中查看最近被修改过的表的方法
1.select uat.table_name from user_all_tables uat 该SQL可以获得所有用户表的名称 2.select object_name, created,last ...
- Flutter学习笔记(16)--Scaffold脚手架、AppBar组件、BottomNavigationBar组件
如需转载,请注明出处:Flutter学习笔记(15)--MaterialApp应用组件及routes路由详解 今天的内容是Scaffold脚手架.AppBar组件.BottomNavigationBa ...
- 暂停研发surging,是否继续维护!
前言 surging从2017 年开始,2 年来利用业余时间为 surging语言添砖加瓦. 这种活雷锋行为并没有得到开发者们的理解,很多人甚至用命令的口吻,灵魂拷问方式要求活雷锋们再苦再累也得免费为 ...
- 面试java后端面经_3
小姐姐说:你一点都不懂表达,一点都不懂爱情,一点也不爱我! 你答:你知道吗,我听说过一个这样的故事,讲的就是有一个小女孩和一个男孩在一起,小男孩呢很不幸是位聋哑人,虽然如此,但是他们的日子过得特别的美 ...
- c# NPOI 导出23万条记录耗时12秒
先上测试代码: string connectionString = "Server=localhost;Initial Catalog=******;User ID=sa;Password= ...
- python+unittest框架第二天unittest之简单认识Test Suite:测试套件
今天了解下测试套件Test Suite,什么是测试套件,测试套件是由多个Test Case测试用例组成的,当然也可以由多个子测试套件组成. 接下来看下如果构建测试套件,构建测试套件的方法: 1.用un ...
- 前端小知识-css3
一.实现图片倒影 如图: css属性 .style{ -webkit-box-reflect:below 0 linear-gradient(transparent,white 50% ,white) ...
- 这些用来审计 Kubernetes RBAC 策略的方法你都见过吗?
原文链接:这些用来审计 Kubernetes RBAC 策略的方法你都见过吗? 认证与授权对任何安全系统来说都至关重要,Kubernetes 也不例外.即使我们不是安全工作人员,也需要了解我们的 Ku ...
- IntelliJ IDEA 2019 快捷键终极大全,速度收藏!
转载注明:https://blog.csdn.net/WantFlyDaCheng/article/details/100078777 自动代码 查询快捷键 其他快捷键 调试快捷键 重构 十大Inte ...
- 良许 | 命令的输出不会保存?居然连 tee 命令都不会用!
很多情况下,我们需要保存程序/命令的输出到本地,常用的一种方法是重定向,这也是一种很好的方法.但有个问题,如果你想要做后续操作,比如要统计输出的行数等,重定向就有困难了. 这时候,tee 命令就派上用 ...