Django小白开发指南
文章目录
- HTTP协议
- socket实现一个web服务器
- WSGI实现一个web服务器
- WSGI实现支持多URL的web服务器
- WSGI实现图片显示的web服务器
- MVC && MTV
- 1.MVC
- 2.MTV
- 3.总结
- 一、创建Django项目
- 1.创建项目
- 2.创建app
- 3.第一次django 请求
- 二、模板
- 1.配置settings.py
- 2.模板语法
- 3.继承模板
- 三、models模型
- 1.常用字段&属性
- 四、设置数据库
- 1.设置mysql库
- 2.mysqldb替换mysql
- 3.数据迁移
- 五、URL路由匹配
- 1.正则匹配
- 2.路由匹配&传参
- 3.管理多个URL文件
- 1.去除重复url路径
- 2.视图传参数
- 六、View视图
- 1.HttpRequest对象
- 2.HttpResponse对象
- 3.CBV-类方法
- 4.通过HttpResponse下载文件
- 5.分页功能
- 七、ORM的增删改查语句
- 1.创建语句
- 2.查询语句
- 3.修改语句
- 4.删除语句
- 5.Filter过滤条件
- 6.多模块关联关系
- 7.Queryset对象方法
- 8.ORM对象操作
- 1.单表对象操作
- 2.外键关联操作
- 3.外键反向关联操作
- 4.多对多操作
- 5.多对多反向操作
- 八、Django会话技术
- 1、cookie工作原理
- 2.Cookie
- 2、CSRF
- 防止CSRF
- 九、ORM-admin后台管理
- 1.管理app下的表(模型)
- 2.自定制admin(管理界面)
- 返回上级目录
HTTP协议
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪“部分,以及哪部分内容首先显示(如文本先于图形)等。
socket实现一个web服务器
# -*- coding:utf-8 -*-
# created by Alex Li - 路飞学城import socketdef main():sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)sock.bind(('localhost', 8000))sock.listen(5)while True:# 等待浏览器访问conn, addr = sock.accept()# 接收浏览器发送来的请求内容data = conn.recv(1024)print(data)# 给浏览器返回内容conn.send(b"HTTP/1.1 200 OK\r\nContent-Type:text/html; charset=utf-8\r\n\r\n")conn.send("<h1 style='color:blue'>电脑前的你长的真好看!</h1>".encode("utf-8"))# 关闭和浏览器创建的socket连接conn.close()if __name__ == "__main__":main()
WSGI实现一个web服务器
- WSGI (Web Server Gateway lnterface) 是一种规范,它定义了使用python编的web app (应用程序) 与web server (socket服务端)之间接口格式,实现web app与web server间的解耦
- 通俗的说:当规范建立后,程序就不再重复编写web server (socket服务端),而是直接使用现成的实现WSGI的模块 (例如:wsgiref、uwsgiwerkzeug),从而让程序员更加专注与业务代码与其重复造轮子,不如直接用现成的。
from wsgiref.simple_server import make_serverdef run_server(environ,start_response):""":param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等:param start_response: 响应相关:return:"""start_response("200 OK",[('Content-Type','text/html;charset=utf-8')])return [bytes('<h1>Hello world!</h1>',encoding='utf-8')]if __name__ == '__main__':httpd = make_server('localhost',8000,run_server)httpd.serve_forever() # 死循环
WSGI实现支持多URL的web服务器
from wsgiref.simple_server import make_serverdef book(environ,start_response):start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])return [bytes('<h1 style="color:pink">book page!</h1>', encoding='utf-8')]def cloth(environ,start_response):start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])return [bytes('<h1 style="color:yellow">cloth page!</h1>', encoding='utf-8')]passdef url_dispacher():urls = {'/book':book,'/cloth':cloth,}return urlsdef run_server(environ,start_response):""":param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等:param start_response: 响应相关:return:"""request_url = environ.get("PATH_INFO") # 获取用户请求的urlurl_list = url_dispacher() # 拿到所有urlif request_url in url_list:func_data = url_list[request_url](environ,start_response)return func_data # 真正返回数据给用户else:start_response("404 ",[('Content-Type','text/html;charset=utf-8')])return [bytes('<h1 style="font-size:50px">404,Page not found!</h1>',encoding='utf-8')]if __name__ == '__main__':httpd = make_server('localhost',8000,run_server)httpd.serve_forever() # 死循环
WSGI实现图片显示的web服务器
from wsgiref.simple_server import make_server
import re
import osBASE_DIR = os.path.dirname(os.path.abspath(__file__))def book(environ,start_response):start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])data = """<h1>欢迎来到日本人专区</h1><img src='/static/imgs/testimg.gif' /><p>上路飞学城,看尽天下小片</p>"""return [bytes(data, encoding='utf-8')]def cloth(environ,start_response):start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])return [bytes('<h1 style="color:yellow">cloth page!</h1>', encoding='utf-8')]passdef url_dispacher():urls = {'/book':book,'/cloth':cloth,}return urlsdef img_handler(request_url):""":param request_url: static/imgs/testimg.gif:return:"""img_path = re.sub('/static','/static_data',request_url)img_abs_path = "%s%s"% (BASE_DIR,img_path)if os.path.isfile(img_abs_path):f = open(img_abs_path,"rb")data = f.read() # 读取文件内容数据return [data,0] # 0:成功读取,1:没有读取return [None,1]def run_server(environ,start_response):""":param environ: 请求相关内容,比如浏览器类型、版本、来源地址、url等:param start_response: 响应相关:return:"""request_url = environ.get("PATH_INFO") # 获取用户请求的urlurl_list = url_dispacher() # 拿到所有urlif request_url in url_list:func_data = url_list[request_url] (environ,start_response) # 调用相应的url函数return func_data # 真正返回数据给用户elif request_url.startswith("/static/"): # 表示图片img_data,img_status = img_handler(request_url)if img_status == 0: # 读取到图片数据start_response("200 OK", [('Content-Type', 'text/html;charset=utf-8')])return [img_data]else:start_response("404 ",[('Content-Type','text/html;charset=utf-8')])return [bytes('<h1 style="font-size:50px">404,Page not found!</h1>',encoding='utf-8')]if __name__ == '__main__':httpd = make_server('localhost',8001,run_server)httpd.serve_forever() # 死循环
MVC && MTV
1.MVC
MVC 是一种使用 MVC (Model View Controller 模型-视图-控制器)设计创建 Web 应用程序的模式
- Model(模型)一般对应数据库操作、纪录的存取
- View (视图)决定着如何展示数据
- Controller (控制器) 负现处理用户交互的部分·控制器负责从视图读取数据,控制用户输入,并向模型发送数据。(urls)
2.MTV
Django是一个MTV框架,其架构模板看上去与传统的MVC架构并没有太大的区别。
Django将MVC中的视图进一步分解为 Django视图(views.py) 和 Django模板(html文件)两个部分,分别决定“展现哪些数据”和“如何展现”,使得Django的模板可以根据需要随时替换,而不仅仅限制于内置的模板,至于MVC控制器部分,由Django框架的URLconf(urls.py)来实现。
3.总结
MVC VIEWS 负责 业务逻辑处理+数据展示
MTV Views 业务逻辑处理
Templates 数据展示
一、创建Django项目
- 要在终端中使用Django创建一个项目,可以按照以下步骤进行操作:
-
打开终端(命令行界面)
-
确保你已经安装了Django。可以通过运行以下命令来检查Django是否已安装:
django-admin --version
如果没有安装Django,可以使用以下命令安装:
pip install django
-
创建项目。在终端中使用以下命令创建一个Django项目:
django-admin startproject project_name
把 “project_name” 替换为你想要的项目名称。这将在当前目录下创建一个名为 “project_name” 的文件夹,其中包含用于构建Django项目所需的文件和目录。
创建应用。在项目目录中使用以下命令创建一个Django应用:
django-admin startapp app_name
把 “app_name” 替换为你想要的应用名称。这将在项目目录下创建一个名为 “app_name” 的文件夹,其中包含用于构建Django应用的文件和目录。
-
进入项目目录。使用以下命令进入刚创建的项目目录:
cd project_name
这会将终端的当前工作目录切换到你的项目目录中。
-
运行开发服务器。在项目目录中,运行以下命令来启动Django的开发服务器:
python manage.py runserver 0.0.0.0:8000
这将运行开发服务器,默认在本地的8000端口上。
-
现在,你可以在浏览器中访问
http://localhost:8000/
来查看新创建的Django项目的初始页面。
这样就完成了在终端中创建一个Django项目的步骤。你可以根据需要在项目中添加应用、模型、视图等。
1.创建项目
django-admin startproject my_site
项目目录结构
mysite
├── manage.py # 管理程序的文件,启动和结束等。
└── my_site├── __init__.py├── settings.py # 程序的配置文件├── urls.py # 程序的路由系统,即:url和处理其函数的对应的关系└── wsgi.py # 指定框架的wsgi
2.创建app
django-admin startapp app01
├── __init__.py 包
├── admin.py 数据库后台
├── apps.py #django 把项目和app 关联起来的一个文件
├── migrations #数据库相关
│ └── __init__.py
├── models.py # 数据库操作地方
├── tests.py # 单元测试
└── views.py # 业务逻辑代码
3.第一次django 请求
- 匹配路由, 路由分发器查找用户请求的url 对应关系,
- 找到了业务函数,就调用
- 找不到就报404
- 业务函数,执行业务逻辑
- 返回数据给浏览器
1。 urls.py 编写路由
2. 在views.py 写一个业务函数2.1 编写业务 代码2.2 通过HttpResponse 方法返回数据给前端3. python manage.py runserver 0.0.0.0:8000
二、模板
1.配置settings.py
- TEMPLATES 配置Html文件,即配置该文件的路径,以便运行程序查找
- 配置jinja引擎,需在该项目下新建一个文件:jinja2_env.py,并添加代码:
# 安装模块:pip install jinja2from django.templatetags.static import static
from django.urls import reverse
from jinja2 import Environmentdef environment(**options):env = Environment(**options)env.globals.update({'static': static,'url': reverse,})return env
# 项目默认配置django引擎
# 若需配置jinja引擎,需添加
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'environment':'django4.jinja2_env.environment', # django4-项目名称,jinja2_env-该项目下新建的jinja2_env.pyTEMPLATES = [ # 模版,html文件# jinja2模板引擎 (在html文件中可以引用函数){'BACKEND': 'django.template.backends.jinja2.Jinja2','DIRS': [BASE_DIR/'templates'],'APP_DIRS': True,'OPTIONS': {# 添加environment,并指定到jinja2_env文件中的environment'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',],},},# django模板引擎{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [BASE_DIR/"templates"], # html 文件夹的位置'APP_DIRS': True,'OPTIONS': {'context_processors': ['django.template.context_processors.debug','django.template.context_processors.request','django.contrib.auth.context_processors.auth','django.contrib.messages.context_processors.messages',],},},
]
2.模板语法
- 在templates目录下的html文件
"""注释"""
{# 单行注释 #}
{% comment %}多行注释
{% endcomment %}"""变量"""
<p>{{ name }}</p>
<p>{{ boddy.2 }}</p> # 列表:索引号取值
<p>{{ addr.city }}</p> # 字典"""if语句"""
{% if age < 18 %}...
{% elif age > 60 %}...
{% else %}...
{% endif %} """结合运算符"""
{% if age >= 18 and age < 60%}
{% if age >= 18 or age < 60%}"""in"""
{% if 'movie' in boddy %}...
{% endif %}"""for循环语句"""
{% for b in boddy %}...
{% endfor %}
"""empty用法"""
{% for b in boddy2 %}...
{% empty %} <p>boddy2为空或不存在</p>
{% endfor %}"""下标"""
{% for foo in boddy %}<p>counter_{{ forloop.counter }} # 下标从1开始counter0_{{ forloop.counter0 }} # 下标从0开始revcounter_{{ forloop.revcounter }} # 下标颠倒从大到小revcounter0_{{ forloop.revcounter0 }} # 下标颠倒从大到小(0)</p>
{% endfor %}"""嵌套语句"""
<table border="2" width="400">{% for star in stars %}{% for s in star %}{{ s }}-{{ forloop.parentloop.counter }}- # 父循环的下标{{ forloop.counter }} # 本次循环下标{% endfor %}{% endfor %}
</table>"""过滤器"""
<p>{{ age }}</p>
<p>{{ age|add:5 }}</p> # add:变量+5
<p>{{ age|add:-5 }}</p> # add:变量-5<p>{{ name|first|upper }}</p> # 将变量name第一个字符串大写
<p>{{ name|last|lower }}</p> # 将变量name最后一个字符串小写
<p>{{ name|title }}</p>
<p>{{ name|truncatechars:3 }}</p> # 将变量name第三个字符串开始截断<p>{{ boddy|join:'+' }}</p> # 列表转字符串<p>{{ boddy2|default:'默认值' }}</p> # 若变量boddy2无值则设置默认值<p>{{ dt|date:'y-m-d' }}</p> # 转成日期格式
<p>{{ dt|date:'Y-M-d' }}</p> """HTML转义"""
<p>{{ code|safe }}</p> # safe:将变量code字符串转义成html格式{% autoescape on %} # 关闭自动转义... # 自动转义字符串内容
{% endautoescape %}{% autoescape off %} # 开启自动转义...
{% endautoescape %}
- 若使用 jinja模板引擎,则可以调用python的函数
<body><h2>jinja2模板语言</h2><hr>{# 可调用python函数range #}{% for i in range(1,10) %}{{ i }}{% endfor %}</body>
</html>
3.继承模板
# 模板快
{% block xxx%}...
{% endblock %}# 继承模板
{% extends 'xxx.html' %}# 继承模板内容:block.super
{% block content %}
{# 默认情况下,子模板会覆盖父模板内容 #}
{# 若想继承父模板内容,需使用block.super #}{{ block.super }}<div><button>content</button></div>
{% endblock %}# 导入其他模板文件:include
{% block head %}
{# 导入其他模板文件 #}{% include 'xxx.html' %}<div><button>head</button></div>
{% endblock %}
三、models模型
- django使用对象关系映射 (0bject Relational Mapping,简称ORM)框架去操控数据库。
models ==> ORM
模型 -> 表
类结构 -> 表结构
对象 -> 表的一条数据
类属性 -> 表的字段
1.常用字段&属性
# 常用字段
CharField:用于存储字符串,可指定最大长度。TextField:用于存储长文本字段,没有长度限制。IntegerField:用于存储整数。FloatField:用于存储浮点数。BooleanField:用于存储布尔值,True或False。DateField:用于存储日期。DateTimeField:用于存储日期和时间。FileField:用于存储文件,文件会被上传到指定目录。ImageField:与FileField类似,但特定于存储图像文件。
# 常用属性
max_length:用于指定字段的最大长度。适用于CharField和TextField等字符串字段类型。null:指定字段是否允许为空。默认为False,即不允许为空。对于关联字段(ForeignKey、OneToOneField等),默认值是True。blank:指定字段在表单中是否可以为空。默认为False,即不能为空。对于关联字段,如果null=True,则默认值为True。default:指定字段的默认值。choices:用于定义字段的选项列表。适用于CharField和IntegerField等字段类型。例如:choices=[(1, ‘男’), (2, ‘女’)]verbose_name:指定字段在后台管理界面中显示的名称。related_name:用于指定反向关系的名称。适用于关联字段(ForeignKey、ManyToManyField等)。unique:指定字段的值是否在数据库中唯一,默认为False。help_text:用于在后台管理界面中显示字段的帮助文本。auto_now:指定每次保存对象时自动更新字段的值为当前时间。适用于DateTimeField和DateField等日期时间字段类型。auto_now_add:指定在创建对象时将字段的值设置为当前时间。适用于DateTimeField和DateField等日期时间字段类型。editable:指定字段是否可编辑。默认为True,表示字段可以在后台管理界面中被编辑。primary_key:指定字段是否为主键。默认为False。db_index:指定是否在数据库中为字段创建索引。默认为False。choices:定义了一个包含键-值对的元组,作为下拉菜单。name / db_column:数据库中的字段名称。upload_to:用于定义上传文件的存储路径。
- models.py
# 注:每次写完模型或添加一个字段都需要进行一次数据迁移,将数据迁移到数据库中!from django.db import modelsclass UserModel(models.Model):# uid 会成为主键,原来默认的id不会创建uid = models.AutoField(auto_created=True,primary_key=True)# CharField:字符串类型# unique:唯一# db_index:数据库索引name = models.CharField(max_length=20,unique=True,db_index=True)# IntegerField:整数类型# default:默认值age = models.IntegerField(default=18)# BooleanFieldL:bool类型sex = models.BooleanField(default=True)# TextField:文本框# null=True:表示可以为空# blank=True:在admin管理页面可以为空info = models.TextField(null=True,blank=True)# FloatField:小数salary = models.FloatField(default=100000.521)# DecimalField:十进制小数# max_digits:最大长度# decimal_places:小数点是几位money = models.DecimalField(max_digits=4,decimal_places=2,default=10.52)
四、设置数据库
- 对象关系映射(Object Relational Mapping),它的实质就是将关系数据(库中的业务数据用对象的形式表示出来并通过面向对象 (Object-Oriented)的方式将这些对象组织起来,实现系统业务逻辑的过程。
1.设置mysql库
# settings.py# 设置mysql
DATABASES = {"default": {"ENGINE": "django.db.backends.mysql","NAME": "myBlog", # 数据库名"USER": "root","PASSWORD": "12345678","HOST": "127.0.0.1","PORT": "3306",}
}
2.mysqldb替换mysql
- python3连接mysql的得使用pymysql,MysqlDB模块300年没更新了,但django默认调用的还是MysQLdb,因此 pymysq有个功能可以让django以为是用了MySQLdb.即在项目目录下的 init.py中加上句代码就好
- 或者直接安装mysqlclient则无需使用该方法:pip install mysqlclient
# __init__.py(项目文件)
import pymysqlpymysql.version_info = (1, 4, 13, "final", 0) # mysqlclient版本问题
pymysql.install_as_MySQLdb()
3.数据迁移
-
同步ORM表结构到数据库(Models.py文件每次写完就需要进行迁移)
-
在项目中如果添加了一个字段,需手动同步到数据库,否则数据库报错没有该字段
-
数据库同步工具:migrations
-
1、生成迁移文件
# app01表示指定的app,若第一次执行,则可以默认不写
python manage.py makemigrations app01
- 2、执行迁移
python manage.py migrate
# settings.py
# 同步app设置,最后写入同步的app名INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','app01',
]
五、URL路由匹配
1.正则匹配
- Django的路由本质上是通过正则表达式来对用户请求的url进行匹配(Django2.0版本前使用正则匹配)
# urls.pyfrom django.urls import path,re_path
from app02 import viewsurlpatterns = [re_path(r'^articles/2003/$',views.article_archive1),# year,month被封装为字典,所以函数形参需写该键值接收re_path(r'^articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$',views.article_archive2),# slug:匹配任意字符串re_path(r'^articles/(?P<arg1>[0-9]{4})/(?P<arg2>[0-9]{2})/(?P<slug>[\w-]+)/$',views.article_archive3),
]
# views.pydef article_archive1(request):return HttpResponse('静态article_2003')def article_archive2(request,year,month):return HttpResponse('动态article %s-%s'%(year,month))def article_archive3(request,arg1,arg2,slug):return HttpResponse('动态article %s-%s-%s'%(arg1,arg2,slug))
2.路由匹配&传参
- Django2.0新用法path
- 自定义方法调用 register_converter()
# urls.pyfrom django.urls import path
from app02 import views# path匹配
urlpatterns = [path('articles/<int:year>',views.new_article1),# str:除了'/'外都能匹配path('articles/<int:year>/<str:date>',views.new_article2),path('articles/<int:year>/<int:month>/<slug:arg>',views.new_article3),# path:'/'也能匹配path('articles/<path:arg>',views.new_article4),
]
# views.pydef new_article1(request,year):return HttpResponse('新用法Path %s'%year)def new_article2(request,year,date):return HttpResponse('新用法Path %s %s'%(year,date))def new_article3(request,year,month,arg):return HttpResponse('新用法Path %s %s %s'%(year,month,arg))def new_article4(request,arg):return HttpResponse('新用法Path %s'%(arg))
- 路由传参
# urls.py
urlpatterns = [path('userdetail/<int:uid>',userdetail,name='myuserdetail'),
]# views.py
def userdetail(request,uid):user = userModel.objects.get(pk=uid) # pk:主键return render(request,'userdetail.html',{'user':user}) # 将user参数传入html文件的user变量# userdetail.html
<body><p>名字:{{ user.name }}</p><p>年龄:{{ user.age }}</p>
</body>
- 命名空间
- 若路径有命名空间,则该命名空间下所有相关的路径都需要添加该命名空间
# urls.py
urlpatterns = [path('app01/',include(('app01.urls','app01'),namespace='app01')),
]# app01:urls.py
urlpatterns = [path('userlist/',userlist,name='myuserlist'), # path('userdetail/<int:uid>',userdetail,name='myuserdetail'),
]# userlist.html
<body># 跳转到命名空间为app01下的myuserdetail的html( url/userdetail/id )<a href="{% url 'app01:myuserdetail' user.id %}"></a>
</body>
- 重定向
# views.py
from django.shortcuts import redirect,reverse# 重定向
def myredirect(request):# return redirect('https://www.baidu.com')# 反向解析# redirect(reverse('myuserdetail'),args=(2,)) ==> 'userdetail/2/'return redirect(reverse('myuserdetail',args=(2,))) # args传参return redirect(reverse('myuserdetail',kwargs={'uid':2})) # 关键字传参# 命名空间return redirect(reverse('app01:myuserdetail',args=(2,))) # args传参return redirect(reverse('app01:myuserdetail',kwargs={'uid':2})) # 关键字传参
3.管理多个URL文件
- 当有多个app时,每个app可以有自己的urls.py,只需在顶级urls.py(项目下的urls)中include一下就可以
# urls.pyfrom django.urls import path,includeurlpatterns = [# 包括了app01和app02项目的urlspath('app01/',include("app01.urls")),path('app02/',include("app02.urls"))
]
1.去除重复url路径
# urls.py# 去除重复的部分url
extra_urls = [path('<int:year>/<str:date>', views.new_article2),path('<int:year>/<int:month>/<slug:arg>', views.new_article3),path('<path:arg>', views.new_article4),
]urlpatterns = [# 去除url重复的路径"articles"部分,匹配结果相同path('articles',include(extra_urls))
]
2.视图传参数
# urls.py
urlpatterns = [# 写一个字典,键表示实参名,值表示传入实参值path('articles/<int:year>',views.new_article1,{'version':'v1.0'}),
]
# views.py
# 获取参数version
def new_article1(request,year,version):return HttpResponse('新用法Path %s-%s'%(year,version))
六、View视图
1.HttpRequest对象
- **request.scheme:**返回请求协议(http/https)
- **request.path:**返回请求页的路径
- **request.method:**返回http请求的方法(get/post/put/delete…)
- **request.GET/request.POST:**返回http请求的参数(方法由HTML文件决定)
- **request.content_type:**返回http请求的类型
- **request.FILES:**返回上传的文件数据
- 获取文件数据,需在HTML文件加上属性 enctype=“multipart/form-data” 告知后台这个表单有文件,将文件单独处理。
- **request.META:**包含所有可用 HTTP头的字典
- **request.get_host():**返回网站服务器地址
- **request.get_port():**返回服务器主机端口
- **request.get_full_path():**返回相对路径(相当于request.path)
- **request.build_absolute_uri(‘location’):**返回url的绝对路径,若添加位置,则附加
- **request.COOKIES:**会话技术
- **request.session:**会话技术
- **request.META[‘REMOTE_ADDR’]😗*客户端的ip地址
# views.py
from django.shortcuts import render,HttpResponsedef index(request):print(request.scheme) # httpprint(request.path) # /app02/indexprint(request.method) # getprint(request.content_type) # text/plainprint(request.GET,request.POST) # <QueryDict: {'username': ['xiaof'], 'password': ['lsf20010929']}>print(request.GET.get('username'),request.POST.get('username')) # 获取字典数据print(request.FILES) # <MultiValueDict: {'my_file': [<InMemoryUploadedFile: CSS.jpeg (image/jpeg)>]}>print(request.META['REMOTE_ADDR']) # 127.0.0.1print(request.META) for k,v in request.META.items():print(k,v)print(request.get_host()) # localhost:8000print(request.get_port()) # 8000print(request.get_full_path()) # /app02/indexprint(request.build_absolute_uri('user=abc/pwd=123')) # http://localhost:8000/app02/user=abc/pwd=123print(request.COOKIES) # 浏览器cookies数据print(request.session)return render(request,'form.html')
- 中间件(防火墙)
- url->中间件->view,中间件相当于防火墙,需关闭相应的安全过滤,才能修改浏览器的请求方法
# 项目的settings.pyMIDDLEWARE = [ # 中间件(防火墙)'django.middleware.security.SecurityMiddleware','django.contrib.sessions.middleware.SessionMiddleware','django.middleware.common.CommonMiddleware',# 'django.middleware.csrf.CsrfViewMiddleware', # 注释即关闭防火墙,使网页可以进行其他请求操作'django.contrib.auth.middleware.AuthenticationMiddleware','django.contrib.messages.middleware.MessageMiddleware','django.middleware.clickjacking.XFrameOptionsMiddleware',
]
2.HttpResponse对象
# 响应
from django.http import JsonResponse# 1.返回字符串
return HttpResponse('OK')
# 2.返回模板:前后端不分离使用
return render(request,'index.html')
# 3.重定向:跳转页码
return HttpResponseRedirect("/")
# 4.返回JSON:前后端分离使用
return JsonResponse({"data":"hello"})
-
**content_type:**用于填充HTTP的数据类型
- 默认情况下为: “ text/html; charset = utf-8”。
-
**status:**HTTP的状态码
# views.pyfrom django.shortcuts import HttpResponsedef index(request):html = """<form method="POST" enctype="multipart/form-data"><input type="text" name="username"><input type="password" name="password"><input type="file" name="my_file"><input type="submit" value="登录"></form>"""res = HttpResponse(html,content_type="text/plain",status=404)
- **HttpResponseRedirect:**状态码:302,临时重定向一个新的位置
- **HttpResponsePermanentRedirecttt:**状态码:301,永久定向到一个新的位置
from django.shortcuts import HttpResponseRedirect,HttpResponsePermanentRedirectttdef test(request):return HttpResponseRedirect("/") # 临时定向到首页return HttpResponsePermanentRedirecttt("/") # 永久定向到首页
3.CBV-类方法
- CBV(Class-Based-View),CBV就是在视图里使用类处理请求。
- 即可以让我们用类写View。这样做的优点主要下面两种:
- 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
- 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
# views.py
from django.views import View# 该类会自动判断调用方法
class TestView(View):def get(self,request):return HttpResponse("Class View get request")def post(self,request):return HttpResponse("Class View post request")pass
- url处理是需要一个可调用的函数,class-based-view提供了一个 as_view() 静态方法
# urls.pyurlpatterns = [path('class_view',views.TestView.as_view()) # 对于类需调用as_view方法
]
- 类继承
# views.py # 类继承
class TestView2(TestView):time = 10
4.通过HttpResponse下载文件
- MIME参考手册:https://www.w3school.com.cn/media/media_mimeref.asp
- 对于文件类型,需参考MIME手册,然后修改 content_type
# views.pydef download_file(request):f = open('static_data/data.xls','rb')res = HttpResponse(f.read(),content_type='application/vnd.ms-excel') # 文件类型为xlsres['Content-Disposition'] = 'attachment; filename="my_data.xls"' # 对下载的文件进行处理return res
5.分页功能
# views.py
from django.core.paginator import Paginatordef paginate(request,page=1):per_page = 10all_data = PersonModel.objects.all()# 分页器paginator = Paginator(all_data,per_page)persons = paginator.page(page) # 获取第page页的数据pages = range(1,per_page+1) # 页面范围,供遍历data = {'persons':persons,'pages':pages}return render(request,'paginate.html',data)
# urls.py
urlspattern = [path('paginate/<int:page>/',paginate,name='paginate'),
]
七、ORM的增删改查语句
1.创建语句
- 方法1:在终端执行以下命令,进入django的数据库环境
python manage.py shell
- 创建数据
from app01 import models# 方法1,object.create创建对象,创建完后数据将自动提交保存到数据库
models.Account.object.create(username = '小枫',email='1848148016@qq.com',password='12345678',
)
# 方法2,先创建数据,再通过save方法提交数据
new_obj = models.Account(username = '小枫',email='1848148016@qq.com',password='12345678',
)
new_obj.save()
- 外键关联 models.ForeignKey(“Account”)
# 方法1,直接在对象里关联 account_id = id值
models.Article.objects.create(title = '如何学Python',content = '日复一日,坚持学习',# 关联的键值必须加上_idaccount_id = 1,pub_date = '2023-7-31',
)
# 方法2,先各自创建表,再进行关联 a1.account = m1对象
# 先创建用户表
m1 = models.Account(username='王五',email='123132@qq.com',password='213123',
)
m1.save()
# 再创建文章表
a1 = models.Article(title='什么是chatggpt',content='人工智能chatgpt',pub_date='2022-10-12',
)
# 关联表
a1.account = m1
a1.save()
- 多对多关联 models.ManyToManyField (“Tag”)
a1 = models.Article(title='什么是chatggpt',content='人工智能chatgpt',account_id = 1,pub_date='2022-10-12',
)
# tags.set,赋值tags对象id为1,3,5
a1.tags.set([1,3,5])
# tags.add,在原记录上加新值tags对象id为1,2,3
a1.tags.add(1,2,3)
articles = models.Article.objects.filter(content__contains='技术') # 过滤出含有关键词的文章
tag = models.Tag.objects.get(id=2) # 获取要关联的标签对象for article in articles:article.tags.add(tag) # 将标签关联到每篇过滤后的文章中
2.查询语句
# __gt:大于
# 查询id大于5的Account对象
models.Account.objects.filter('id__gt=5')
# startswith:以什么开头
# 查询以密码为a开头的Account对象
models.Account.objects.filter('password__startswith='a')
# , : 和
# 查询id大于5的Account对象并且psw是123
models.Account.objects.filter('id__gt=5,password='123')
3.修改语句
# 批量修改
models.Account.objects.filter(id__gt=1).update(password='1234556')# 单条修改
a = models.Account.objects.get(id=1)
a.username = 'job'
a.save()
4.删除语句
- 相关联的表数据也会被删除
# 批量删除
models.Account.objects.filter(id__gt=1).delete()# 单条删除
a = models.Account.objects.get(id=1)
a.delete()
5.Filter过滤条件
- 一般在前面加上is表示对字母大小写不敏感,可返回多个对象
gt:大于
it:小于
ite:小于等于
gte:大于等于
statswith:以什么开头
endswith:以什么结尾
contains:包含
models.Account.objects.filter(password__contains="1")
in:判断是否存在并返回
models.Account.objects.filter(id__in=(2,3))
range:区间过度,可对数字、日期进行过滤
import datetime
start_date = datetime.date(2022,12,15)
end_date = datetime.date(2023,8,1)
models.Account.objects.filter(register_date__range=(start_date,end_date))
date:查具体哪一天内容
models.Account.objects.filter(register_date__date="2023-7-31")
models.Account.objects.filter(register_date__date__gt="2023-7-31") # 配合gt使用
year、month、day:查哪一年、哪一月份、哪一天
models.Account.objects.filter(register_date__year="2023")
models.Account.objects.filter(register_date__month="12")
models.Account.objects.filter(register_date__day="15")
week:查询一年的第几周(52)
week_day:查星期几,从1(星期日)到7(星期六)
models.Account.objects.filter(register_date__week_day=2) # 星期一
hour、mintue、second:查每天的哪小时、哪分钟、哪一秒
models.Account.objects.filter(register_date__hour=8)
models.Account.objects.filter(register_date__mintue=15)
models.Account.objects.filter(register_date__second=15)
regex:正则表达式
models.Account.objects.filter(password__regex=r"^(1)")
- 方法2:在views.py 里写函数,对模型对象进行操作
- 同时需配置路由url
from django.shortcuts import render,HttpResponse
from django.db.models import Max,Min,Sum,Avg,Count
from app01.models import *# Create your views here.
def add_person(request):# 方式1# p = PersonModel()# try:# p.name='xiaoM'# p.age=21# p.save()# except Exception as e:# return HttpResponse('add fail')# return HttpResponse('add success!')# 方式2# try:# p = PersonModel(name='xiaoK',age=22)# p.save()# except Exception as e:# return HttpResponse('add fail')# return HttpResponse('add success!')# 方式3try:PersonModel.objects.create(name='ku',age=23)except Exception as e:return HttpResponse('add fail')return HttpResponse('add success!')def del_person(request):try:PersonModel.objects.filter(age__gt=20).delete()except Exception as e:return HttpResponse('delete fail')return HttpResponse('delete success!')def update_person(request):try:# p = PersonModel.objects.filter(age__gt=23).update(age=100)p = PersonModel.objects.get(id=5)p.age = 18p.save()except Exception as e:print(e)return HttpResponse('update fail')return HttpResponse('update success!')def get_person(request):try:# p = PersonModel.objects.get(id=5)# print(p.name,p.age)p = PersonModel.objects.all()for o in p:print(o.name,o.age)except Exception as e:print(e)return HttpResponse('get fail')return HttpResponse('get success!')# 聚合函数
def aggregate(request):p = PersonModel.objects.aggregate(Max('age'))p = PersonModel.objects.aggregate(Min('age'))p = PersonModel.objects.aggregate(Sum('age'))p = PersonModel.objects.aggregate(Count('age'))p = PersonModel.objects.aggregate(Avg('age'))print(p)# 排序p = PersonModel.objects.all().order_by('age') # 升序p = PersonModel.objects.all().order_by('age','id')p = PersonModel.objects.all().order_by('-age') # 降序print(p)return HttpResponse('Success!')
6.多模块关联关系
-
1.关联分类
- ForeignKey:一对多,将字段定义在多的端中
- ManyToManyField:多对多,将字段定义在两端的任意一端中
- OneToOneField:一对一,将字段定义在任意一端中
-
2.外键关联
- ForeignKey:一对多关系
- OneToOneField:一对一关系
from django.db import models# 创建模型A
class ModelA(models.Model):name = models.CharField(max_length=100)# 创建模型B
class ModelB(models.Model):name = models.CharField(max_length=100)model_a = models.ForeignKey(ModelA, on_delete=models.CASCADE) # 建立一对多关系 model_a = models.OneToOneField(ModelA, on_delete=models.CASCADE) # 建立一对一关联
- on_delete参数
# 注意:修改on_delete参数之后需要重新同步数据库
user_type = models.ForeignKey(UserType,on_delete=models.CASCADE)models.CASCADE默认值(Django1.11) # 表示级联删除,即删除UserType时胡关联的User也会被删除
models.PROTECT # 保护模式,阻止级联删除。(若无外键关联可删除)
models.SET_NULL # 置空模式,设为null,nuLL=True参数必须具备
modeLs.SET_DEFAULT # 置默认值设为默认值,default参数必须具备
models.SET() # 删除的时候重新动态指向一个安体访问对应元素,可传两数
modeLs.DO_NOTHING什么也不做。(Django1.11) # 有外键约束
- 外键查询
# 正向查询:直接调用关联的键查询
print(user.user_type.name)
print(user.user_type.id)
# 反向查询
# 内部自动生成 user_set 属性供反向查询
print(user_type.user_set.all()) # 返回QuerySet
print(user_type.user_set.filter(id=1))# reLated_name:关联名称,设置反向查询的名称,原本使用user_set改为users
user_type = models.ForeignKey(UserType,,reLated_name=users)
print(user_type.users.all())
- 3.多对多关联
from django.db import models# 创建模型A
class ModelA(models.Model):name = models.CharField(max_length=100)model_b = models.ForeignKey('ModelB', on_delete=models.CASCADE)# 创建模型B
class ModelB(models.Model):name = models.CharField(max_length=100)model_a = models.ForeignKey(ModelA, on_delete=models.CASCADE)
# 使用
m1 = ModelA.object.get(id=1)
m1.model_b.all()m2 = ModelB.object.get(id=1)
m2.model_a.all()
7.Queryset对象方法
all():返回所有数据
- 可在models.py 文件中的类加上__ str __方法,在该方法中写上初始化的字符串,调用all方法时将自动调用该初始化字符串
# models.py
class Account(models.Model):"""账户表"""username = models.CharField(max_length=64,unique=True)email = models.EmailField(unique=True)password = models.CharField(max_length=255)register_date = models.DateTimeField(auto_now_add=True)signature = models.CharField("签名",max_length=255,null=True)# str方法在调用all方法时自动调用def __str__(self):return self.username# python manage.py shell
modles.Account.objects.all() # 自动返回该类的初始化str方法
exclude():使用方法与filter()相同,结果与filter相反;排除符合条件的数据
models.Account.objects.exclude(register_date__date='2023-6-15')
values():将数据都封装成一个字典
a = models.Account.objects.all()
a.values()
# 通过键直接取该相应的值(字典)
a.values('username')
order_by():多字段排序
# 通过id进行顺序排序
a.values('id','register_date').order_by('id')
# 通过id进行逆序排序
a.values('id','register_date').order_by('id')# 通过register_date进行顺序,若相同则根据id进行排序
a.values('id','register_date').order_by('register_date','id')
reverse():反转顺序,使用前必须先进行排序
a.values('id','register_date').reverse()
a.order_by('id').reverse()
get():精确查询一条数据(必须存在的数据),返回一个对象
a = models.Account.objects.get(id=1)
a = models.Account.objects.get(id__id=1) # 必须只存在一条大于1的数据
# 直接调用
a.username
8.ORM对象操作
1.单表对象操作
o = models.Artilce.objects.all()[0]
o.title
2.外键关联操作
o = models.Artilce.objects.all()[0]
o.account.username
3.外键反向关联操作
- article_set是动态生成的,被外键关联的类,会自动根据关联的类名加上 _set,通过该属性可以反向查找
a = models.Account.objects.get(name='job')
a.article_set.all()
a.article_set.select_related() # 使用效果与all相同
4.多对多操作
a = models.Article.objects.get(id=5)
a.tags.all()
a.tags.select_related() # 使用效果与all相同
5.多对多反向操作
t = models.Tag.objects.get(name='科技')
t.article_set.all()
a.article_set.select_related()
八、Django会话技术
1、cookie工作原理
2.Cookie
- 使用response的方法
import datetimefrom django.shortcuts import render,HttpResponse,redirect,reverse
from app01.models import *# 获取cookie
def index(request):# cookie# 获取该页面的cookie为userid的值,若无则设为0userid = request.COOKIES.get('userid',0)# 获取登录的用户user = userModel.objects.filter(id=userid).first()return render(request,'index.html',{'user':user})# 设置cookie
def login(request):if request.method == 'GET':return render(request, 'login.html')elif request.method == 'POST':# 1、接收前端提交过来的数据uname = request.POST.get('uname') # 参数为html的name属性值passwd = request.POST.get('passwd')# 2、登录验证users = userModel.objects.filter(username=uname,password=passwd)if users.exists():# 获取当前登录的用户对象user = users.first()response = redirect(reverse('index'))# 3、设置cookieresponse.set_cookie('userid',user.id) # 创建cookie# 设置过期时间# response.set_cookie('userid',user.id,max_age=7*24*3600) # max_age:秒# response.set_cookie('userid',user.id,# expires=datetime.datetime(2023,9,5))response.set_cookie('userid', user.id, # timedelta:时间差expires=datetime.datetime.now()+datetime.timedelta(days=10))# 跳转到登录页面return responsereturn HttpResponse("当前账户不存在或账户密码有误,请重新输入或注册!")# 删除cookie
def logout(request):response = redirect(reverse('index'))# 注销、删除cookieresponse.delete_cookie('userid')request.session.delete(session_key)return response
- session
- 使用request的方法
import datetime
from django.shortcuts import render,HttpResponse,redirect,reverse
from app01.models import *# 获取session
def index(request):# sessionuserid = request.session.get('userid',0)# 获取登录的用户user = userModel.objects.filter(id=userid).first()return render(request,'index.html',{'user':user})# 设置session
def login(request):if request.method == 'GET':return render(request, 'login.html')elif request.method == 'POST':# 1、接收前端提交过来的数据uname = request.POST.get('uname') # 参数为html的name属性值passwd = request.POST.get('passwd')# 2、登录验证users = userModel.objects.filter(username=uname,password=passwd)if users.exists():# 获取当前登录的用户对象user = users.first()response = redirect(reverse('index'))# 3.设置sessionrequest.session['userid'] = user.idrequest.session.set_expiry(7*24*3600) # 设置过期时间return responsereturn HttpResponse("当前账户不存在或账户密码有误,请重新输入或注册!")# 删除session
def logout(request):response = redirect(reverse('index'))# 注销、删除sessionsession_key = request.session.session_keyrequest.session.delete(session_key)return response
2、CSRF
- CSRF全拼为Cross Site Request Forgery,跨站请求伪造
- CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求
- 包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账…
- 造成的问题:个人隐私泄露以及财产安全
防止CSRF
- Django下的CSRF预防机制
django第一次响应来自某个客户端的请求时,会在服务器端随机生成一个 token,把这个token 放在 cookie里。然后每次 POST请求都会带上这个 token,这样就能避免被CSRF攻击。 - 在Post请求时,表单中添加 {% csrf_token %}
<form action="" method="post">{# 禁止csrf安全验证 #}{% csrf_token %}...
</form>
九、ORM-admin后台管理
- 创建一个admin,用于登录 ‘localhost:8000/admin’
# 在项目的目录下执行
python manage.py createsuperuser
1.管理app下的表(模型)
- 注册对应的模型,在该app项目的admin.py上写
# app01/ admin.py
from app01 import modelsadmin.site.register(models.Account)
admin.site.register(models.Article)
admin.site.register(models.Tag)
2.自定制admin(管理界面)
# app01 --admin.py
# admin自定制
class AccountAdmin(admin.ModelAdmin):list_display = ('username','email','register_date','signature') # 显示列表search_fields = ('username','email') # 搜索内容list_filter = ('register_date',) # 过滤list_per_page = 5 #分页,每页几条数据list_editable = ['signature',] # 可在列表修改的属性class ArticleAdmin(admin.ModelAdmin):list_display = ('title','pub_date','account')fields = ('title','content',('pub_date','tags'))# 可自定义显示范围exclude = ('account',) # 与fields相反,不显示某字段date_hierarchy = 'pub_date' # 按日期分类显示fieldsets = (('文章内容',{'fields':('title','content'),'classes':('wide','extrapretty'), # 样式}),('发布相关',{'fields':('account','pub_date'),'classes':('collapse',), # 可折叠}))# 只能针对多对多# filter_vertical = ('tags',)filter_horizontal = ('tags',)radio_fields = {'account':admin.HORIZONTAL} # 由下拉框变单选框autocomplete_fields = ['account',] # 外键自动补全,可用于查询数据admin.site.register(models.Account,AccountAdmin) #模型与管理类相关联
admin.site.register(models.Article,ArticleAdmin)
admin.site.register(models.Tag)
- 在admin管理后台,如果添加的字段可为空时,需在models.py 在该字段添加属性 blank=True
- 一般null和blank同时使用(null作用于数据库)
class Account(models.Model):"""账户表"""signature = models.CharField("签名",max_length=255,null=True,blank=True) # blank与admin配合使用
- 将多对多关联显示到列表
- 在 models.py 上自定义方法,在admin.py引入(若不自定义方法无法显示)
# admin.py
class Article(models.Model):def get_tags(self):return ', '.join([i.name for i in self.tags.all()])# admin.py
class ArticleAdmin(admin.ModelAdmin):list_display = ('title','pub_date','account','get_tags')
-
添加HTML样式
- 在 models.py 上写该属性的html样式,在admin.py上显示
- 注意:添加新字段需要手动将数据同步到数据库,否则数据库没有该数据报错
- python manage.py makemigrations app01
- python mange.py migrate
# models.py from django.utils.html import format_htmlclass Tag(models.Model):color_code = models.CharField(max_length=6)def colored_name(self):return format_html('<span style="color:#{};">{}</span>',self.color_code,self.name,)# admin.py class TagAdmin(admin.ModelAdmin):list_display = ['name','colored_name']
-
自定义表单名称
- 在 models.py 各表类中添加类 Meta,添加属性 verbose_name_plural
- 在各表字段自定义名称,直接在字段添加属性 verbose_name
- 在 models.py 各表类中添加类 Meta,添加属性 verbose_name_plural
# models.pyclass Account(models.Model):class Meta:# verbose_name = '账户' # 存在复数形式verbose_name_plural = '账户'class Article(models.Model):tags = models.ManyToManyField("Tag",verbose_name='标签')class Meta:verbose_name_plural = '文章'class Tag(models.Model): class Meta:verbose_name_plural = '标签'
返回上级目录
import sys
sys.path.append('..') # 返回上级目录
相关文章:

Django小白开发指南
文章目录 HTTP协议socket实现一个web服务器WSGI实现一个web服务器WSGI实现支持多URL的web服务器WSGI实现图片显示的web服务器MVC && MTV1.MVC2.MTV3.总结 一、创建Django项目1.创建项目2.创建app3.第一次django 请求 二、模板1.配置settings.py2.模板语法3.继承模板 三…...

保序回归与金融时序数据
保序回归在回归问题中的作用是通过拟合一个单调递增或递减的函数,来保持数据点的相对顺序特性。 一、保序回归的作用 主要用于以下情况: 1. 有序数据:当输入数据具有特定的顺序关系时,保序回归可以帮助保持这种顺序关系。例如&…...

基于单片机设计的家用自来水水质监测装置
一、前言 本文介绍基于单片机设计的家用自来水水质监测装置。利用STM32F103ZET6作为主控芯片,结合水质传感器和ADC模块,实现对自来水水质的检测和监测功能。通过0.96寸OLED显示屏,将采集到的水质数据以直观的方式展示给用户。 随着人们对健…...

ubuntu20.04运用startup application开机自启动python程序
运用startup application开机自启动python程序。在终端中输入gnome-session-properties,如果显示没有则先进行安装,sudo apt-get update 和sudo apt install StartupApplications(根据显示提示安装)。在显示程序中搜索startup,打开应用程序。 在程序目录…...

SpringBoot整合Caffeine实现缓存
Caffeine Caffeine是一种基于Java的高性能缓存库,它提供了可配置、快速、灵活的缓存实现。Caffeine具有以下特点: 高性能:Caffeine使用了一些优化技术,如基于链表的并发哈希表和无锁算法,以提供卓越的读写性能。容量…...

DVWA-弱会话IDS
弱会话IDS Session简介: 用户登录后,在服务器就会创建一个会话(session),叫做会话控制,接着访问页面的时候就不用登录,只需要携带Session去访问即可。 sessionID作为特定用户访问站点所需要的唯一内容。如果能够计算…...

【C++中cin、cin.get()、cin.getline()、getline() 的区别】
文章目录 引入cin基本用法输入多个变量换行符存放在缓冲区中 cin.get()基本用法重载函数换行符残留在缓冲区中 cin.getline()基本使用重载函数换行符不会残留在缓冲区中 string 流中的 getline()总结用法总结几个输入实例输入格式输入格式输入格式输入格式 输出格式 写在最后 引…...

SSH连接华为交换机慢
ssh连接交换机慢是因为交换计算密钥算法阶段默认使用安全性更高的秘钥,由于性能问题导致连接比较慢,如一台华为S5735S-L24T4S-QA2的交换机默认使用如下秘钥,安全行由高到低。 ssh server key-exchange dh_group16_sha512 dh_group15_sha512 …...

Web攻防03_MySQL注入_数据请求
文章目录 PHP-MYSQL-数据请求类型1、数字型(无符号干扰)2、字符型(有符号干扰)3、搜索型(有多符号干扰)4、框架型(有各种符号干扰) PHP-MYSQL-数据请求方法数据请求方法GET:POST:Coo…...

JS加密/解密那些必须知道的事儿
一直以来,字符串的编码问题对于新手程序员来说,或者平常不太涉猎这方面的程序员来说,是犹如灵异学一样的存在。经常会遇到莫名其妙的编码问题,导致的各种的无法理解的错误。 今天,本问就来介绍一下作者所知晓的一切…...

搭建伪分布式Hadoop
文章目录 一、Hadoop部署模式(一)独立模式(二)伪分布式模式(三)完全分布式模式 二、搭建伪分布式Hadoop(一)登录虚拟机(二)上传安装包(三…...

【C++】特殊类的设计(只在堆、栈创建对象,单例对象)
🌏博客主页: 主页 🔖系列专栏: C ❤️感谢大家点赞👍收藏⭐评论✍️ 😍期待与大家一起进步! 文章目录 一、请设计一个类,只能在堆上创建对象二、 请设计一个类,只能…...

分类预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入分类预测
分类预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入分类预测 目录 分类预测 | MATLAB实现基于GRU-AdaBoost门控循环单元结合AdaBoost多输入分类预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现基于GRU-AdaBoost门控循环单元结…...

【Spring Boot项目】根据用户的角色控制数据库访问权限
文章目录 简介方法一添加数据库依赖配置数据库连接创建用户角色表创建Spring Data JPA实体和仓库实现自定义的网关过滤器配置网关过滤器几个简单的测试API 方法二创建数据库访问接口实现数据库访问接口创建用户角色判断逻辑创建网关过滤器配置网关过滤器 总结 简介 在一些特定…...

EthernetIP 转MODBUS RTU协议网关连接FANUC机器人作为EthernetIP通信从站
远创智控YC-EIPM-RTU网关产品是一款高效的数据采集工具,它可以通过各种数据接口与工业领域的仪表、PLC、计量设备等产品连接,实时采集这些设备中的运行数据、状态数据等信息。采集到的数据经过整合和运算等操作后,可以被传输到其他设备或者云…...

如何注册微信小程序
如何注册微信小程序 前言 因为最近沉迷和朋友们一起下班去打麻将,他们推荐了一个计分的小程序,就不需要每局都转账或者用扑克牌记录了,但是这个小程序不仅打开有广告,各个页面都植入了广告,用起来十分不适。 于是我…...

移动App安全检测的必要性,app安全测试报告的编写注意事项
随着移动互联网的迅猛发展,移动App已经成为人们日常生活中不可或缺的一部分。然而,虽然App给我们带来了便利和乐趣,但也伴随着一些潜在的安全风险。黑客、病毒、恶意软件等威胁着用户的隐私和财产安全,因此进行安全检测就显得尤为…...

DVWA-JavaScript Attacks
JavaScript Attacks JavaScript Attack即JS攻击,攻击者可以利用JavaScript实施攻击。 Low 等级 核心源码,用的是dom语法这是在前端使用的和后端无关,然后获取属性为phrase的值然后来个rot13和MD5双重加密在复制给token属性。 <script&…...

算法通关村第二关|白银|链表反转拓展【持续更新】
1.指定区间反转 1.1 头插法:将区间内遍历到的结点插入到起始处之前。 public ListNode reverseBetween(ListNode head, int left, int right) {ListNode dummyNode new ListNode(-1);dummyNode.next head;ListNode pre dummyNode;// 将pre移动到区间的前一位&a…...

开发者职场“生存状态”大调研报告分析 - 第四版
听人劝、吃饱饭,奉劝各位小伙伴,不要订阅该文所属专栏。 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 跨域学习者,从事过全栈研发、产品经理等工作,现任研发部门 CTO 。荣誉:2022年度博客之星Top4、博客专家认证、全栈领域优质创作者、新星计划导师,“星荐官共赢计…...

代码与细节(一)
在用到 Java17的新特性 Unmodifiable Lists 时不知道你是否和我有同样的惊讶 为什么弄了这么多重载方法? 先说结论:为了性能。 其实一细想,都能想明白:varargs(可变参数) 的背后是数组的内存分配和初始化,相比正常的…...

AI绘画使用Stable Diffusion(SDXL)绘制中国古代神兽
一、引言 说到神奇异兽,脑海中首先就会跳出我国古代神话传说中的各种神兽。比如青龙、白虎、朱雀、玄武,再比如麒麟、凤凰、毕方、饕餮等等,这些都是大家耳熟能详的的神兽。 这些神兽不仅体现了人们丰富的创造力和想象力,更是我…...

老卫带你学---leetcode刷题(148. 排序链表)
148. 排序链表 问题: 给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。 示例 1:输入:head [4,2,1,3] 输出:[1,2,3,4]示例 2:输入:head [-1,5,3,4,0] 输出:[-1…...

21.1 stm32使用LTDC驱动LCD--配置说明
本文讲解如何配置LTDC驱动LCD的参数配置,以及CubeMx参数配置说明 本文使用的是淘宝买的一块带电容触摸的液晶显示屏:5寸TFT液晶显示屏高清800*480免驱40P通用RGBIPS全视角彩屏GT911 说实话,价格还是相对挺便宜的,值得入手…...

zabbix监控nginx的状态页面
zabbix监控nginx的状态页面 文章目录 zabbix监控nginx的状态页面1.环境说明2.所涉及到的知识点3.在nginx主机上安装zabbix_agent4.开启nginx状态显示页面5.进入zabbix的web页面配置主机,监控项,触发器5.1.添加主机5.2.创建监控项5.3.创建触发器 1.环境说…...

C语言初学者工具选择:vscode + MSYS2 + cmake 搭建 C环境
文章目录 前言1. MSYS2 安装1. 下载安装包2. 安装3. pacman 换清华大学源4. 安装 mingw-w64 toolchain 和 cmake ninja5. 将 toolchain 加入系统环境变量 2. 设置 vscode1. 必要的插件2. 一个简单的 vscode cmake 项目 最后C数据结构与算法CMake 前言 网上关于使用 vscode 配…...

【四:httpclient的使用】
目录 1、Demo案例2、请求一个带cookies的get请求3、请求一个带cookies的post请求案例一,案例二的properties的配置 1、Demo案例 public class MyHttpClient {Testpublic void test1() throws IOException {//用来存放我们的结果String result;HttpGet get new Htt…...

在innodb引擎中,count(*)、count(1)、count(主键)、count(字段)哪个性能最高?
在InnoDB引擎中,这四种计数值的效率高低取决于具体的数据库和数据表结构,无法一概而论哪个性能最高。不过,一般情况下可以按照以下顺序进行选择: count():统计所有行的数量。由于InnoDB引擎的行锁是锁住整行ÿ…...

华为OD 跳格子2(200分)【java】B卷
华为OD统一考试A卷B卷 新题库说明 你收到的链接上面会标注A卷还是B卷。目前大部分收到的都是B卷。 B卷对应20022部分考题以及新出的题目,A卷对应的是新出的题目。 我将持续更新最新题目 获取更多免费题目可前往夸克网盘下载,请点击此链接进入:…...

javascript/python 笔记: folium feature group自动切换
1 python部分 python部分只能是静态的结果 1.1 导入库 import folium import math 1.2 数据 cell_lst表示基站位置,location_lst表示 用户实际位置(均为伪数据) cell_lst[[1.341505, 103.682498],[1.342751, 103.679604],[1.341505, 10…...