pt28django教程

缓存

缓存是一类可以更快的读取数据的介质统称,读取硬盘、较复杂的计算、渲染都会产生较大的耗时。数据变化频率不会很高的场景适合使用缓存。使用缓存场景:博客列表页、电商商品详情页、缓存导航及页脚。

Django中设置缓存

Django中提供多种缓存方式,如需使用需要在settings.py中进行配置

初始化配置
[root@vm ~]# mysql -uroot -p123456 -e 'create database mysite7 default charset utf8;'[root@vm ~]# django-admin startproject mysite7
[root@vm ~]# cd mysite7/
[root@vm mysite7]# vim mysite7/settings.pyALLOWED_HOSTS = ['*',]DATABASES = {'default' : {'ENGINE': 'django.db.backends.mysql','NAME': 'mysite7','USER': 'root','PASSWORD': '123456','HOST': '127.0.0.1','PORT': '3306',}
}
LANGUAGE_CODE = 'zh-Hans'TIME_ZONE = "Asia/Shanghai"[root@vm mysite7]# python3 manage.py runserver 0.0.0.0:8000
[root@vm mysite7]# python3 manage.py migrate
[root@vm mysite7]# mysql -uroot -p123456 -e 'use mysite7;show tables;'
1、数据库缓存

mysite7 改配置 migrate , 添加缓存配置项 createcachetable

Django可以将其缓存的数据存储在您的数据库中

[root@vm mysite7]# vim mysite7/settings.py
#添加到最后
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.db.DatabaseCache','LOCATION': 'my_cache_table','TIMEOUT': 300,  #缓存保存时间 单位秒,默认值为300, 'OPTIONS':{'MAX_ENTRIES': 300, #缓存最大数据条数'CULL_FREQUENCY': 2,#缓存条数达到最大值时 删除1/2的缓存数据}}
}

创建缓存表

[root@vm mysite7]# python3 manage.py createcachetable
[root@vm mysite7]# mysql -uroot -p123456 -e 'desc mysite7.my_cache_table;'
+-----------+--------------+------+-----+---------+-------+
| Field     | Type         | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+-------+
| cache_key | varchar(255) | NO   | PRI | NULL    |       |
| value     | longtext     | NO   |     | NULL    |       |
| expires   | datetime(6)  | NO   | MUL | NULL    |       |
+-----------+--------------+------+-----+---------+-------+
2、文件系统缓存
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache','LOCATION': '/var/tmp/django_cache',#这个是文件夹的路径#'LOCATION': 'c:\test\cache',#windows下示例}
}
3、本地内存缓存
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache','LOCATION': 'unique-snowflake'}
}

Django中使用缓存

在urls中使用(较少)
from django.views.decorators.cache import cache_pageurlpatterns = [path('foo/', cache_page(60)(my_view)  ),
]
在模板中使用(较少)
{% load cache %}        {% cache 500 sidebar username %}.. sidebar for logged in user ..
{% endcache %}
在Views中使用
from django.views.decorators.cache import cache_page@cache_page(30)  -> 单位s
def my_view(request):...

使用举例

[root@vm mysite7]# vim mysite7/urls.py
from . import views
urlpatterns = [path('test_cache/',views.test_cache),
...[root@vm mysite7]# vim mysite7/views.py
from django.http import HttpResponse
import timedef test_cache(request):t = time.time()# 经历了复杂计算或复杂查询time.sleep(10)return HttpResponse("time is %s" % t)
http://192.168.1.11:8000/test_cache/     #访问很慢,network栏,看到用时10s
缓存装饰器

不灵活,不方便修改清理

[root@vm mysite7]# vim mysite7/views.py
from django.http import HttpResponse
import time
from django.views.decorators.cache import cache_page@cache_page(600)
def test_cache(request):...
http://192.168.1.11:8000/test_cache/     #第一次很慢,后面很快,但是时间没变化
[root@vm net_note]# mysql -uroot -p123456 -e 'select * from mysite7.my_cache_table\G'
缓存api

作用:局部缓存部分结果,

set、get、delete、add 、get_or_set、set_many、get_many、delete_many

#指定配置引入,多个缓存import  caches
from django.core.cache import caches
cache1 = caches['myalias']
cache2 = caches['myalias_2']#默认配置引入【指的配置中的default项】 等同于 caches['default']
from django.core.cache import cache#常规命令 set
#key: 字符串类型
#value: Python对象
#timeout:缓存存储时间  默认值为settings.py CACHES对应配置的TIMEOUT
#返回值:None
cache.set('my_key', 'myvalue', 30)#常规命令 get
#返回值:为key的具体值,如果没有数据,则返回None
cache.get('my_key')
#可添加默认值,如果没取到返回默认值
cache.get('my_key', 'default值')#常规命令 delete
#返回值  None
cache.delete('my_key')#常规命令 add 只有在key不存在的时候 才能设置成功
#返回值 True or False
cache.add('my_key', 'value') #如果my_key已经存在,则此次赋值失效#常规命令 get_or_set 如果未获取到数据 则执行set操作
#返回值 key的值
cache.get_or_set('my_key', 'value', 10)#常规命令 get_many(key_list) set_many(dict,timeout)
#返回值  set_many:返回插入不成功的key数组 
#       get_many:取到的key和value的字典
>>> cache.set_many({'a': 1, 'b': 2, 'c': 3})
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}#常规命令 delete_many
#返回值  成功删除的数据条数
cache.delete_many(['a', 'b', 'c'])
[root@vm mysite7]# python3 manage.py shell
>>> from django.core.cache import cache
>>> cahe.set('user','django',600)
>> cache.get('user')
'django'
>>> cache.delete('user')
>>> cache.get('user')>>> cache.add('user','django',600)
True
>>> cache.add('user','django',600)
False
>>> cache.get('user')
'django'>>> cache.get_or_set('user2','django',600)
'django'
>>> cache.get_or_set('user2','dj',600)
'django'

浏览器中的缓存

强缓存

不会向服务器发送请求,直接从缓存中读取资源

Expires

缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点
Expires: Thu, 02 Apr 2030 05:14:08 GMT
Expires是 HTTP/1 的产物,受限于本地时间,如果修改了本地时间,可能会造成缓存失效

Cache-Control

在HTTP/1.1中,Cache-Control主要用于控制网页缓存。
比如当Cache-Control:max-age=120  代表请求创建时间后的120秒,缓存失效

一般情况下两个值都会设置,浏览器查看Response Header里的Expires、Cache-Control

协商缓存

协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程

Last-Modified和If-Modified-Since
第一次访问时,服务器会返回文件的最近修改时间 Last-Modified: 
浏览器下次请求时 携带If-Modified-Since这个header , 该值为 Last-Modified
服务器接收请求后,对比结果,若资源未发生改变,则返回304,否则返回200并将新资源返回给浏览器

缺点:只能精确到秒,容易发生单秒内多次修改,检测不到

ETag和If-None-Match

​ Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成。流程同上,判断是否match。

对比Last-Modified:Etag精度高、Etag优先级高、性能不如Last-Modifi

中间件 Middleware

中间件是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。

每个中间件组件负责做一些特定的功能。例如,Django 包含一个中间件组件 AuthenticationMiddleware,它使用会话将用户与请求关联起来。

中间件类:

中间件类须继承自 django.utils.deprecation.MiddlewareMixin

中间件类须实现下列五个方法中的一个或多个:

  • def process_request(self, request): 执行路由之前被调用,在每个请求上调用,返回None或HttpResponse对象
  • def process_view(self, request, callback, callback_args, callback_kwargs): 调用视图之前被调用,在每个请求上调用,返回None或HttpResponse对象
  • def process_response(self, request, response): 所有响应返回浏览器 被调用,在每个请求上调用,返回HttpResponse对象
  • def process_exception(self, request, exception): 当处理过程中抛出异常时调用,返回一个HttpResponse对象
  • def process_template_response(self, request, response): 在视图函数执行完毕且试图返回的对象中包含render方法时被调用;该方法需要返回实现了render方法的响应对象

注: 中间件中的大多数方法在返回None时表示忽略当前操作进入下一项事件,当返回HttpResponese对象时表示此请求结束,直接返回给客户端

编写中间件类:
[root@vm mysite7]# mkdir middleware
[root@vm mysite7]# vim middleware/mymiddleware.pyfrom django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixinclass MyMiddleWare(MiddlewareMixin):def process_request(self, request):print("中间件方法 process_request 被调用")def process_view(self, request, callback, callback_args, callback_kwargs):print("中间件方法 process_view 被调用")def process_response(self, request, response):print("中间件方法 process_response 被调用")return response
注册中间件:
[root@vm mysite7]# vim mysite7/settings.py
...
MIDDLEWARE = [...'middleware.mymiddleware.MyMiddleWare',]
使用测试验证
[root@vm mysite7]# vim mysite7/urls.py
urlpatterns = [
...path('test_mw', views.test_mw),path('test_mw2', views.test_mw2),[root@vm mysite7]# vim mysite7/views.py
...    
def test_mw(request):print('---view in test_mw---')return HttpResponse("test mw is OK!")def test_mw2(request):print('---view in test_mw2---')return HttpResponse('test mw2 is OK!')    
访问http://192.168.1.11:8000/test_mw    test mw is OK!
终端日志:中间件方法 process_request 被调用中间件方法 process_view 被调用---view in test_mw---中间件方法 process_response 被调用
访问http://192.168.1.11:8000/test_mw2  也会有日志显示,影响全局 
中间件执行的顺序

重新复制一套MyMiddleWare2 访问,执行顺序如下,进和出方向正好相反(洋葱图了解)

访问http://192.168.1.11:8000/test_mw 中间件方法 process_request 被调用中间件方法2 process_request 被调用中间件方法 process_view 被调用中间件方法2 process_view 被调用---view in test_mw---中间件方法2 process_response 被调用中间件方法 process_response 被调用

在这里插入图片描述

练习

用中间件实现强制某个IP地址只能向/test 发送 5 次GET请求提示:- request.META['REMOTE_ADDR'] 可以得到远程客户端的IP地址- request.path_info 可以得到客户端访问的GET请求路由信息- 在进url之前统计次数,做出处理
[root@vm mysite7]# vim middleware/mymiddleware.py
from django.http import HttpResponse
from django.utils.deprecation import MiddlewareMixin
import reclass MyMW(MiddlewareMixin):# 统计每一个客户端IP以及对应的访问次数visit_times = {}def process_request(self, request):# 1. 只对/test开头的路由做5次访问的限制if not re.match(r'^/test', request.path_info):return# 2. 获取客户端的IP地址cip = request.META['REMOTE_ADDR']# 3. 获取访问次数,回去cip的次数,默认是0次times = self.visit_times.get(cip, 0)# 4. 判断是否超过5次if times >= 5:return HttpResponse("no way!")# 5.每访问一次,次数+1self.visit_times[cip] = times + 1print('%s visit we %s times' % (cip,self.visit_times[cip]))[root@vm mysite7]# vim mysite7/settings.py'middleware.mymiddleware.MyMW',                                   

访问测试,看日志输出 192.168.1.1 visit we 1 times 5次后看浏览器返回no way

跨站请求伪造攻击 CSRF

跨站请求伪造攻击

某些恶意网站上包含链接、表单按钮或者JavaScript,它们会利用登录过的用户在浏览器中的认证信息(cookie)试图在你的网站上完成某些操作,这就是跨站请求伪造(CSRF,即Cross-Site Request Forgey)。

说明: CSRF中间件和模板标签提供对跨站请求伪造简单易用的防护。

作用: 不让其它表单提交到此 Django 服务器

防范步骤:

打开MIDDLEWARE

打开MIDDLEWARE中django.middleware.csrf.CsrfViewMiddleware,默认打开

添加csrf_token

模板中,form标签下添加如下标签

    <form action=....>{% csrf_token %}...</form>

关闭个别试图csrf

如果某个视图不需要django进行csrf保护,可以用装饰器关闭对此视图的检查

from django.views.decorators.csrf import csrf_exempt@csrf_exempt
def my_view(request):return HttpResponse('Hello world')

使用测试

[root@vm mysite7]# vim mysite7/urls.pypath('test_csrf', views.test_csrf),[root@vm mysite7]# vim mysite7/views.py
from django.http import HttpResponse
from django.shortcuts import renderdef test_csrf(request):if request.method == 'GET':return render(request, "test_csrf.html")elif request.method == 'POST':name = request.POST['name']return HttpResponse("欢迎您,%s" % name)[root@vm mysite7]# vim mysite7/settings.py
TEMPLATES = [{'BACKEND': 'django.template.backends.django.DjangoTemplates','DIRS': [os.path.join(BASE_DIR,'templates')],[root@vm mysite7]# mkdir -p templates
[root@vm mysite7]# vim templates/test_csrf.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>CSRF</title>
</head>
<body><form action="/test_csrf" method="post"><p>名称:<input type="text" name="name"></p><input type="submit" value="提交"></form>
</body>
</html>
#访问  http://192.168.1.11:8000/test_csrf   输入名称,提交,
# 报CSRF验证失败. 请求被中断. 看下面的help里的 {% csrf_token %} template tag
#写到form表单里<form action="/test_csrf" method="post">{% csrf_token %}<p>名称:<input type="text" name="name"></p><input type="submit" value="提交"></form>#再次访问查看网页源代码,多出一个csrf的token
<input type="hidden" name="csrfmiddlewaretoken" value="oqLeUQSpIy...>点击"提交"按钮,中间件的方法先于视图函数被调用,在中间方法中验证,先前给你的csrfmiddlewaretoken,验证存在并正确放行,调用视图函数完成相应的功能。

web分页功能

分页是指在web页面有大量数据需要显示,为了阅读方便在每个页页中只显示部分数据。

好处: 方便阅读;减少数据提取量,减轻服务器压力。

Django通过使用Paginator和Page这两个类来完成的分页

Paginator对象

负责分页数据整体的管理,位于django.core.paginator 模块中。

对象的构造方法paginator = Paginator(object_list, per_page)
参数object_list 需要分类数据的对象列表per_page 每页数据个数
返回值: Paginator的对象Paginator属性- count:需要分类数据的对象总数- num_pages:分页后的页面总数- page_range:从1开始的range对象, 用于记录当前面码数- per_page 每页数据的个数Paginator方法- page(number)- 参数 number为页码信息(从1开始)- 返回当前number页对应的页信息- 如果提供的页码不存在,抛出InvalidPage异常Paginator异常exception- InvalidPage:总的异常基类,包含以下两个异常子类- PageNotAnInteger:当向page()传入一个不是整数的值时抛出- EmptyPage:当向page()提供一个有效值,但是那个页面上没有任何对象时抛出

Page对象

负责具体某一页的数据的管理,Paginator对象的page()方法返回Page对象

创建对象   page = paginator.page(页码)Page对象属性- object_list:当前页上所有数据对象的列表- number:当前页的序号,从1开始- paginator:当前page对象相关的Paginator对象Page对象方法- has_next():如果有下一页返回True- has_previous():如果有上一页返回True- has_other_pages():如果有上一页或下一页返回True- next_page_number():返回下一页的页码,如果下一页不存在,抛出InvalidPage异常- previous_page_number():返回上一页的页码,如果上一页不存在,抛出InvalidPage异常- len():返回当前页面对象的个数说明:  Page 对象是可迭代对象,可以用 for 语句来 访问当前页面中的每个对象
参考文档 <https://docs.djangoproject.com/en/2.2/topics/pagination/>

分页示例:

视图函数

from django.core.paginator import Paginator
def book(request):  # 1. 准备要分页的数据bks = Book.objects.all()# 2. 创建分页器    paginator = Paginator(bks, 10)# 3. 获取当前页码cur_page = request.GET.get('page', 1)# 4. 根据页码获取页面对象page = paginator.page(cur_page)# 5. 返回响应return render(request, 'bookstore/book.html', locals())

模板设计

<html>
<head><title>分页显示</title>
</head>
<body>
{% for b in page %}<div>{{ b.title }}</div>
{% endfor %}{% if page.has_previous %}
<a href="{% url 'book' %}?page={{ page.previous_page_number }}">上一页</a>
{% else %}
上一页
{% endif %}{% for p in paginator.page_range %}{% if p == page.number %}{{ p }}{% else %}<a href="{% url 'book' %}?page={{ p }}">{{ p }}</a>{% endif %}
{% endfor %}{% if page.has_next %}
<a href="{% url 'book' %}?page={{ page.next_page_number }}">下一页</a>
{% else %}
下一页
{% endif %}
</body>
</html>

使用示例

[root@vm mysite7]# vim mysite7/urls.pypath('test_page', views.test_page,name='book'),[root@vm mysite7]# vim mysite7/views.py
...
from django.core.paginator import Paginator
def test_page(request):# 1. 准备要分页的数据list_data = ['a', 'b', 'c', 'd', 'e']# 2. 创建分页器paginator = Paginator(list_data, 2)# 3. 获取当前页码cur_page = request.GET.get('page', 1)# 4. 根据页码获取页面对象page = paginator.page(cur_page)# 5. 返回响应return render(request, "test_page.html",locals())[root@vm mysite7]# vim templates/test_page.html
<html>
<head><title>分页显示</title>
</head>
<body>
{% for b in page %}<div>{{ b }}</div>
{% endfor %}{% if page.has_previous %}
<a href="{% url 'book' %}?page={{ page.previous_page_number }}">上一页</a>
{% else %}
上一页
{% endif %}{% for p in paginator.page_range %}{% if p == page.number %}{{ p }}{% else %}<a href="{% url 'book' %}?page={{ p }}">{{ p }}</a>{% endif %}
{% endfor %}{% if page.has_next %}
<a href="{% url 'book' %}?page={{ page.next_page_number }}">下一页</a>
{% else %}
下一页
{% endif %}
</body>
</html>     #访问验证http://192.168.1.11:8000/test_page

csv文件下载

Django可直接在视图函数中生成csv文件 并响应给浏览器

import csv
from django.http import HttpResponse
from .models import Bookdef make_csv_view(request):response = HttpResponse(content_type='text/csv')response['Content-Disposition'] = 'attachment; filename="mybook.csv"'all_book = Book.objects.all()writer = csv.writer(response)writer.writerow(['id', 'title'])for b in all_book:    writer.writerow([b.id, b.title])return response
  • 响应获得一个特殊的MIME类型text / csv。这告诉浏览器该文档是CSV文件,而不是HTML文件
  • 响应会获得一个额外的Content-Disposition标头,其中包含CSV文件的名称。它将被浏览器用于“另存为…”对话框
  • 对于CSV文件中的每一行,调用writer.writerow,传递一个可迭代对象,如列表或元组。
[root@vm mysite7]# vim mysite7/urls.pypath('test_csv', views.test_csv),
[root@vm mysite7]# vim mysite7/views.py
import csv
from django.http import HttpResponse
from .models import Bookdef test_csv(request):# 1. 创建响应对象时,指定响应的内容的类型是csvresponse = HttpResponse(content_type='text/csv')# 2. 告诉浏览器以附件的方式处理响应数据,文件名为mybook.csvresponse['Content-Disposition'] = 'attachment; filename="mybook.csv"'# 3. 获取数据# all_book = Book.objects.all()all_book = [{'id': 1, 'title': 'java'},{'id': 2, 'title': 'python'},{'id': 3, 'title': 'php'},]# 4. 创建一个csv格式的写入器,将数据写入到responsewriter = csv.writer(response)# 5. 调用写入器的方式writerow,写入一行数据,标题writer.writerow(['编号', '图书名称'])# 6. 写入数据for b in all_book:writer.writerow([b['id'], b['title']])return response#访问  http://192.168.1.11:8000/test_csv     产生下载

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

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

相关文章

Mac电脑视频处理工具 Topaz Video AI for mac

Topaz Video AI是一款强大而易用的视频处理软件&#xff0c;通过人工智能技术提供高质量的视频增强和编辑功能。它可以帮助用户改善视频的质量、修复缺陷、优化图像&#xff0c;并提供丰富的编辑选项&#xff0c;以满足个性化的视频处理需求。无论是专业摄影师、视频编辑人员&a…

五、3d场景的卡片展示的创建

在我们3d的开发中&#xff0c;对某一些建筑和物体进行解释说明是非常常见的现象&#xff0c;那么就不得不说卡片的展示了&#xff0c;卡片展示很友好的说明了当前物体的状态&#xff0c;一目了然&#xff0c;下面就是效果图。 它主要有两个方法来实现&#xff0c;大量的图片建议…

maven找不到jar包

配置settings.xml文件之后出现报错找不到jar包 先改maven设置: 然后在重新清理构建项目: 可以通过执行以下命令清理本地 Maven 仓库 mvn dependency:purge-local-repository

渗透测试之打点

请遵守中华人民共和国网络安全法 打点的目的是获取一个服务器的控制权限 1. 企业架构收集 &#xff08;1&#xff09;官网 &#xff08;2&#xff09;网站或下属的子网站&#xff0c;依次往下 天眼查 企查查 2. ICP 备案查询 ICP/IP地址/域名信息备案管理系统 使用网站…

京东大型API网关实践之路

概述 1、背景 京东作为电商平台&#xff0c;近几年用户、业务持续增长&#xff0c;访问量持续上升&#xff0c;随着这些业务的发展&#xff0c;API网关应运而生。 API网关&#xff0c;就是为了解放客户端与服务端而存在的。对于客户端&#xff0c;使开放给客户端的接口标准统…

26342-2010 国际运尸 木质棺柩.

声明 本文是学习GB-T 26342-2010 国际运尸 木质棺柩. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本标准规定了国际运尸木质棺柩的分类、规格、技术要求、检验方法、包装、运输和储存。 本标准适用于为国际运尸木质棺柩的设计、生产、检测…

第七天:gec6818开发板QT和Ubuntu中QT安装连接sqlite3数据库驱动环境保姆教程

sqlite3数据库简介 帮助文档 SQL Programming 大多数关系型数的操作步骤&#xff1a;1&#xff09;连接数据库 多数关系型数据库都是C/S模型 (Client/Server)sqlite3是一个本地的单文件关系型数据库&#xff0c;同样也有“连接”的过程 2&#xff09;操作数据库 作为程序员&am…

如何将matlab中的mat矩阵文件在python中读取出来

先安装hdf5storage这个包 pip3 install hdf5storage 然后在当前目录下放入要读取的mat文件 # 将matlab中的mat文件读取出来 import hdf5storagedata hdf5storage.loadmat(inputWeights.mat) print(data[inputWeights])

分布式搜索引擎Elasticsearch

一、Elasticsearch介绍 1.Elasticsearch产生背景 大数据量的检索NoSql: not only sql,泛指非关系型的数据库Nginx的7层负载均衡和4层负载均衡2.Elasticsearch是什么 一个基于Lucene的分布式搜索和分析引擎,一个开源的高扩展的分布式全文检索引擎 Elasticsearch使用Java开发…

RNN模型与NLP应用(1/9):数据处理基础Data Processing Basics

文章目录 处理分类特征把分类特征转化为数值特征应用one-hot编码indice要从1开始而不能从0开始数据处理为什么使用one-hot向量 处理文本数据Step1&#xff1a;将文本分割成单词Step2&#xff1a;计算单词的频度按频度递减的方式排序 Step3&#xff1a;One-Hot编码 处理分类特征…

Stm32_标准库_GPIOA初始化

代码&#xff1a; #include "stm32f10x.h" // Device headerGPIO_InitTypeDef GPIO_InitStructur;//定义变量结构体int main(void){/*使用RCC开启GPIO的时钟*/RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启PA端口时钟/*使用GPIO_I…

黑马VUE3视频笔记

目录 一、使用create-vue创建项目 二、setup选项 三、reactive和ref函数 1.reactive() 2.ref() 三、computed 四、watch ​五、生命周期函数 六、父传子、子传父 父传子defineProps 子传父defineEmits 七、模板引用 ref defineExpose 八、跨层传递普通数据 prov…

JAXB(Java Architecture for XML Binding)下载、使用

简介 JAXB&#xff08;Java Architecture for XML Binding&#xff09;就是XML数据绑定的java架构。JAXB可以根据XML Schema生成java类&#xff0c;也能根据java类生成XML Schema&#xff0c;能将XML数据unmarshall到Java内容树&#xff0c;也能将Java内容树持久化为XML数据。…

【煤矿虚拟仿真体验】VR采煤机技能培训有效提高训练效果

在我们的社会中&#xff0c;能源是至关重要的。它是推动我们日常生活和工作的主要动力。然而&#xff0c;我们在获取这种能源的过程中&#xff0c;也带来了许多环境问题。煤矿开采是其中的一个重要部分&#xff0c;因此我们需要寻找更环保、更安全的方式来进行煤矿开采。VR&…

手把手教你用 Milvus 和 Towhee 搭建一个 AI 聊天机器人

作为向量数据库的佼佼者&#xff0c;Milvus 适用于各种需要借助高效和可扩展向量搜索功能的 AI 应用。 举个例子&#xff0c;如果想要搭建一个聊天机器人&#xff0c;Milvus 一定是其进行数据管理的首选。那么&#xff0c;如何让这个应用程序开发变得易于管理及更好理解&#x…

LeetCode算法二叉树—222. 完全二叉树的节点个数

目录 222. 完全二叉树的节点个数 - 力扣&#xff08;LeetCode&#xff09; 代码&#xff1a; 运行结果&#xff1a; 给你一棵 完全二叉树 的根节点 root &#xff0c;求出该树的节点个数。 完全二叉树 的定义如下&#xff1a;在完全二叉树中&#xff0c;除了最底层节点可能…

2023-09-28 monetdb-db,schema,user,role-分析

摘要: 对moentdb的database,schema,user,role和权限做分析, 以与mysql中的概念做对比分析. 备份: https://stoneatom.yuque.com/staff-ft8n1u/qfqtnb/gfqc62fozh0qsyqm 上下文相关: 2023-09-28 mysql-代号m-schema调研-文档记录-CSDN博客 2023-09-28 monetdb-databae的概念和…

湖南软件测评公司简析:软件功能测试和非功能测试的联系和区别

一、软件功能测试   软件功能测试旨在验证软件是否按照需求规格说明书的要求正常工作。具体而言&#xff0c;功能测试会对软件的所有功能进行测试&#xff0c;以确保其满足用户的需求和预期。在进行功能测试时&#xff0c;根据需求规格说明书编写测试用例&#xff0c;并在测试…

时序预测 | MATLAB实现POA-CNN-BiLSTM鹈鹕算法优化卷积双向长短期记忆神经网络时间序列预测

时序预测 | MATLAB实现POA-CNN-BiLSTM鹈鹕算法优化卷积双向长短期记忆神经网络时间序列预测 目录 时序预测 | MATLAB实现POA-CNN-BiLSTM鹈鹕算法优化卷积双向长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 MATLAB实现POA-CNN-BiLSTM鹈鹕算…

ad18学习笔记十一:显示和隐藏网络、铺铜

如何显示和隐藏网络&#xff1f; Altium Designer--如何快速查看PCB网络布线_ad原理图查看某一网络的走线_辉_0527的博客-CSDN博客 AD19(Altium Designer)如何显示和隐藏网络 如何显示和隐藏铺铜&#xff1f; Altium Designer 20在PCB中显示或隐藏每层铺铜-百度经验 AD打开与…