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

在Django中安装、配置、使用CKEditor5,并将CKEditor5录入的文章展现出来,实现一个简单博客网站的功能

在Django中可以使用CKEditor4和CKEditor5两个版本,分别对应软件包django-ckeditor和django-ckeditor-5。原来使用的是CKEditor4,python manager.py makemigrations时总是提示CKEditor4有安全风险,建议升级到CKEditor5。故卸载了CKEditor4,安装配置CKEditor5,具体步骤如下:

1. 安装CKEditor5(Debian系统):

sudo pip3 install django-ckeditor-5

2. 将“django_ckeditor_5”添加到settings.py的INSTALLED_APPS中:

INSTALLED_APPS = ['django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','django_ckeditor_5',......
]

3. 在settings.py中配置CKEditor5(官网标准设置):

  STATIC_URL = '/static/'MEDIA_URL = '/media/'MEDIA_ROOT = os.path.join(BASE_DIR, 'media')customColorPalette = [{'color': 'hsl(4, 90%, 58%)','label': 'Red'},{'color': 'hsl(340, 82%, 52%)','label': 'Pink'},{'color': 'hsl(291, 64%, 42%)','label': 'Purple'},{'color': 'hsl(262, 52%, 47%)','label': 'Deep Purple'},{'color': 'hsl(231, 48%, 48%)','label': 'Indigo'},{'color': 'hsl(207, 90%, 54%)','label': 'Blue'},]CKEDITOR_5_CUSTOM_CSS = 'path_to.css' # optionalCKEDITOR_5_FILE_STORAGE = "path_to_storage.CustomStorage" # optionalCKEDITOR_5_CONFIGS = {'default': {'toolbar': ['heading', '|', 'bold', 'italic', 'link','bulletedList', 'numberedList', 'blockQuote', 'imageUpload', ],},'extends': {'blockToolbar': ['paragraph', 'heading1', 'heading2', 'heading3','|','bulletedList', 'numberedList','|','blockQuote',],'toolbar': ['heading', '|', 'outdent', 'indent', '|', 'bold', 'italic', 'link', 'underline', 'strikethrough','code','subscript', 'superscript', 'highlight', '|', 'codeBlock', 'sourceEditing', 'insertImage','bulletedList', 'numberedList', 'todoList', '|',  'blockQuote', 'imageUpload', '|','fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor', 'mediaEmbed', 'removeFormat','insertTable',],'image': {'toolbar': ['imageTextAlternative', '|', 'imageStyle:alignLeft','imageStyle:alignRight', 'imageStyle:alignCenter', 'imageStyle:side',  '|'],'styles': ['full','side','alignLeft','alignRight','alignCenter',]},'table': {'contentToolbar': [ 'tableColumn', 'tableRow', 'mergeTableCells','tableProperties', 'tableCellProperties' ],'tableProperties': {'borderColors': customColorPalette,'backgroundColors': customColorPalette},'tableCellProperties': {'borderColors': customColorPalette,'backgroundColors': customColorPalette}},'heading' : {'options': [{ 'model': 'paragraph', 'title': 'Paragraph', 'class': 'ck-heading_paragraph' },{ 'model': 'heading1', 'view': 'h1', 'title': 'Heading 1', 'class': 'ck-heading_heading1' },{ 'model': 'heading2', 'view': 'h2', 'title': 'Heading 2', 'class': 'ck-heading_heading2' },{ 'model': 'heading3', 'view': 'h3', 'title': 'Heading 3', 'class': 'ck-heading_heading3' }]}},'list': {'properties': {'styles': 'true','startIndex': 'true','reversed': 'true',}}
}

其中定义了三种配置,分别为“default”,“extends”和“list”,下面主要使用“extends”。

4. 为了使用中文字体,需要修改extends配置,增加fontFamily设置,将中文字体放在英文字体的前面。

  'fontFamily': {'options': ['微软雅黑', '宋体', '黑体', '仿宋', '楷体', '隶书', '幼圆', 'Arial', 'Times New Roman', 'Verdana', 'Helvetica', 'Georgia', 'Courier New', 'Impact', 'Comic Sans MS', 'Trebuchet MS'],'supportAllValues': 'true',},

 效果如下:

5. 为了使用方便,需要设置字体大小,根据word的使用习惯,按字号来设置字体, 修改extends配置,增加fontSize设置。

(1) 如果需要下拉列表的字体大小和设置字体大小一样,可以如下设置:

    'options': [{ 'model':'56px', 'title': "初号"},{ 'model':'48px', 'title': "小初"},{ 'model':'34.7px', 'title': "一号"},{ 'model':'32px', 'title': "小一"},{ 'model':'29.3px', 'title': "二号"},{ 'model':'24px', 'title': "小二"},{ 'model':'21.3px', 'title': "三号"},{ 'model':'20px', 'title': "小三"},{ 'model':'18.7px', 'title': "四号"},{ 'model':'16px', 'title': "小四"},{ 'model':'14px', 'title': "五号"},{ 'model':'12px', 'title': "小五"},{ 'model':'10px', 'title': "六号"},{ 'model':'8.7px', 'title': "小六"},{ 'model':'7.3px', 'title': "七号"},{ 'model':'6.7px', 'title': "八号"},],'supportAllValues': 'true',},

效果如下:

(2) 如果不需要下拉列表的字体大小和实际字体大小一样,可以增加显示格式设置,将下拉列表字体大小都统一为14px:

  'fontSize': {'options': [{ 'model':'56px', 'title': "初号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'48px', 'title': "小初", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'34.7px', 'title': "一号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'32px', 'title': "小一", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'29.3px', 'title': "二号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'24px', 'title': "小二", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'21.3px', 'title': "三号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'20px', 'title': "小三", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'18.7px', 'title': "四号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'16px', 'title': "小四", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'14px', 'title': "五号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'12px', 'title': "小五", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'10px', 'title': "六号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'8.7px', 'title': "小六", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'7.3px', 'title': "七号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'6.7px', 'title': "八号", 'view': {'styles': { "font-size": '14px' }}},],'supportAllValues': 'true',},

效果如下:

我个人使用了第二种,另外加上一些常规设置,settings.py中CKEditor5的全部设置如下:

STATIC_ROOT = os.path.join(BASE_DIR,"static/")
MEDIA_URL = "media/"
MEDIA_ROOT = os.path.join(BASE_DIR,"media/")CKEDITOR_5_CONFIGS = {
'default': {'toolbar': ['heading', '|', 'bold', 'italic', 'link','bulletedList', 'numberedList', 'blockQuote', 'imageUpload', ],
},
'extends': {'blockToolbar': ['paragraph', 'heading1', 'heading2', 'heading3','|','bulletedList', 'numberedList','|','blockQuote',],'toolbar': ['heading', '|', 'outdent', 'indent', '|', 'bold', 'italic', 'link', 'underline', 'strikethrough','code','subscript', 'superscript', 'highlight', '|', 'codeBlock', 'sourceEditing', 'insertImage','bulletedList', 'numberedList', 'todoList', '|',  'blockQuote', 'imageUpload', '|','fontSize', 'fontFamily', 'fontColor', 'fontBackgroundColor', 'mediaEmbed', 'removeFormat','insertTable',],'image': {'toolbar': ['imageTextAlternative', '|', 'imageStyle:alignLeft','imageStyle:alignRight', 'imageStyle:alignCenter', 'imageStyle:side',  '|'],'styles': ['full','side','alignLeft','alignRight','alignCenter',]},'table': {'contentToolbar': [ 'tableColumn', 'tableRow', 'mergeTableCells','tableProperties', 'tableCellProperties' ],'tableProperties': {'borderColors': customColorPalette,'backgroundColors': customColorPalette},'tableCellProperties': {'borderColors': customColorPalette,'backgroundColors': customColorPalette}},'heading' : {'options': [{ 'model': 'paragraph', 'title': 'Paragraph', 'class': 'ck-heading_paragraph' },{ 'model': 'heading1', 'view': 'h1', 'title': 'Heading 1', 'class': 'ck-heading_heading1' },{ 'model': 'heading2', 'view': 'h2', 'title': 'Heading 2', 'class': 'ck-heading_heading2' },{ 'model': 'heading3', 'view': 'h3', 'title': 'Heading 3', 'class': 'ck-heading_heading3' }]},'fontFamily': {'options': ['微软雅黑', '宋体', '黑体', '仿宋', '楷体', '隶书', '幼圆', 'Arial', 'Times New Roman', 'Verdana', 'Helvetica', 'Georgia', 'Courier New', 'Impact', 'Comic Sans MS', 'Trebuchet MS'],'supportAllValues': 'true',},'fontSize': {'options': [{ 'model':'56px', 'title': "初号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'48px', 'title': "小初", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'34.7px', 'title': "一号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'32px', 'title': "小一", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'29.3px', 'title': "二号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'24px', 'title': "小二", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'21.3px', 'title': "三号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'20px', 'title': "小三", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'18.7px', 'title': "四号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'16px', 'title': "小四", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'14px', 'title': "五号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'12px', 'title': "小五", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'10px', 'title': "六号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'8.7px', 'title': "小六", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'7.3px', 'title': "七号", 'view': {'styles': { "font-size": '14px' }}},{ 'model':'6.7px', 'title': "八号", 'view': {'styles': { "font-size": '14px' }}},],'supportAllValues': 'true',},'height': '800px',
},
'list': {'properties': {'styles': 'true','startIndex': 'true','reversed': 'true',}
}
}# Define a constant in settings.py to specify file upload permissions
CKEDITOR_5_FILE_UPLOAD_PERMISSION = "authenticated"  # Possible values: "staff", "authenticated", "any"CKEDITOR_5_USER_LANGUAGE=True #使用Django配置的语言

 6.修改项目的urls.py,如下所示:

from django.conf import settings
from django.conf.urls.static import staticurlpatterns = [path('admin/login/', sign_in, name='admin_login'),  #替代admin原始登录界面path('admin/', admin.site.urls),......
]urlpatterns += [
path("ckeditor5/", include('django_ckeditor_5.urls')),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

7. 在项目应用(假设为myapp)的models.py中新建CKEditor类:

from django.db import models
from django_ckeditor_5.fields import CKEditor5Fieldclass CkeditorArt(models.Model):#content = models.TextField(verbose_name='内容')article_id = models.AutoField(primary_key=True)title = models.CharField(max_length=200,verbose_name='标题',default='CKEditor编辑页面')content = CKEditor5Field('内容',config_name='extends')#定义模型在admin管理界面显示名称,也可在admin.py中新建ModelAdmin类使用list_display来设置def __str__(self):return f"{self.title},{self.content}"

8. 在项目应用(myapp)的forms.py中新建表单类:

from django import forms
from django_ckeditor_5.widgets import CKEditor5Widget
from .models import CkeditorArtclass PostAdminForm(forms.ModelForm):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.fields["content"].required = Falsetitle = forms.CharField(label='文章标题',max_length=200, required=True, widget=forms.TextInput(attrs={"placeholder": "在这里输入标题",'style': 'width: 500px;'}),)class Meta:model = CkeditorArtfields = ('title','content')widgets = {"content": CKEditor5Widget(attrs={"class": "django_ckeditor_5"}, config_name="extends")}

此处的CKEditor的配置config_name为前面setttings.py中设置extends配置。

9. 为便于使用Django后台管理CKEditor表单提交的内容,在项目应用(myapp)的admin.py中增加如下内容:

from .models import CkeditorArt
class CkeditorArtAdmin(admin.ModelAdmin):list_display =  ('title','content')
admin.site.register(CkeditorArt,CkeditorArtAdmin)

 10. 更新数据库和static文件

python3 manage.py makemigrations
python3 manage.py migrate
python3 manage.py collectstatic

11. 在项目应用(myapp)的urls.py中设置路径:

from django.urls import path
from . import viewsurlpatterns = [path('Ckeditor/', views.Ckeditor, name='ckeditor'),.....]

12. 在项目应用(myapp)的views.py中新建上面提到的view函数Ckeditor:

from django.shortcuts import render
from django.http import HttpResponse
from .forms import PostAdminForm@login_required(login_url='/login/')  #需要登录用户权限
def Ckeditor(request):""" 自定义form表单 """if request.method == 'POST':form = PostAdminForm(data=request.POST)if form.is_valid():form.save()return render(request, 'form-post-finished.html')form = PostAdminForm()return render(request, 'ckeditor-form.html', {'form':form})

13. 在项目应用(myapp)的templates目录下新建上面提到的ckeditor-form.html,主要内容如下:

{% extends "newdesign/newbase.html" %}{% block mytitle %}  <title>Ckeditor富文本编辑</title>{% endblock %}{% block maincontent %}<div class="row"><form method="post", class="form-horizontal">{% csrf_token %}<p>标题: {{form.title |safe}}</p><p>文章内容:</p> {{form.content |safe}}{{form.media}}<input type="submit" value="Submit"></form></div>       {% endblock %}

通过地址/myapp/Ckeditor即可访问CKEditor编辑页面,可以直接把word排版好的内容拷贝过来,格式和照片等都可以按word的排版正常显示。

14. 在CKEditor表单页面输入文章标题,完成文章内容,示例如下,然后submit提交。

提交后可以在Django的管理后台看到相关记录:

 15. 下面将所有文章以列表的形式在网页上展示出来,点击列表中文章的标题,即可展示文章内容,效果如下:

 

 (1) 在项目应用(myapp)的urls.py中设置bloglist和每篇文章的路径:

from django.urls import path
from . import viewsurlpatterns = [path('Ckeditor/', views.Ckeditor, name='ckeditor'),path('bloglist/', views.Bloglist, name='bloglist'),   path('blog/<str:article_id>/', views.Showblog, name='showblog'),   
]

(2) 在项目应用(myapp)的views.py中新建上面提到的view函数Bloglist和Showblog:

from .models import CkeditorArt
#@login_required(login_url='/login/')
def Showblog(request,article_id):try:article = CkeditorArt.objects.get(article_id=article_id)return render(request, 'showblog.html', {'content':article.content,'title':article.title})except CkeditorArt.DoesNotExist:message = '<h1 style="color: red;">文章没找到!<h1>'return render(request, 'showblog.html', {'content':message,'title':'文章没找到'})#@login_required(login_url='/login/')
def Bloglist(request):#values返回字典,values_list返回元组objs = CkeditorArt.objects.values('article_id','title')context = {'objs':objs,}return render(request,'bloglist.html', context) 

(3) 在项目应用(myapp)的templates目录下新建上面提到的bloglist.html和showblog.html

bloglist.html

{% extends "newdesign/newbase.html" %}{% block mytitle %}<title>BLOG列表</title>{% endblock %}{% block maincontent %}  <h1>这是CkEditor编辑的BLOG清单</h1><div><ul>{% for obj in objs %}<h5>文章{{obj.article_id}}: <a href="/myapp/blog/{{ obj.article_id }}/">{{obj.title}}</a></h5>{% endfor %}</ul></div>{% endblock %}

showblog.html

{% extends "newdesign/newbase.html" %}{% block mytitle %}  <title>{{title}}</title>{% endblock %}{% block maincontent %}<h2>{{title}}</h2>{{content|safe}}{% endblock %}

至此,通过CKEditor就基本实现了一个简单博客网站的功能。

相关文章:

在Django中安装、配置、使用CKEditor5,并将CKEditor5录入的文章展现出来,实现一个简单博客网站的功能

在Django中可以使用CKEditor4和CKEditor5两个版本&#xff0c;分别对应软件包django-ckeditor和django-ckeditor-5。原来使用的是CKEditor4&#xff0c;python manager.py makemigrations时总是提示CKEditor4有安全风险&#xff0c;建议升级到CKEditor5。故卸载了CKEditor4&…...

AI笔筒操作说明及应用场景

AI笔筒由来&#xff1a; 在快节奏的现代办公环境中&#xff0c;我们一直在寻找既能提升效率、增添便利&#xff0c;又能融入企业文化、展现个人品味的桌面伙伴。为此&#xff0c;我们特推出专为追求卓越、注重细节的您设计的AI笔筒礼品版&#xff0c;它集高科技与实用性于一身…...

Android自启动管控

1. 自启动管控需求来源 自启动、关联启动、交叉启动、推送启动等现象的泛滥除了对个人信息保护带来隐患外&#xff0c;还会导致占用过多的系统CPU和内存资源&#xff0c;造成系统卡顿、发热、电池消耗过快&#xff1b;还可能引入一些包含“恶意代码”的进程在后台隐蔽启动&…...

把握鸿蒙生态崛起的机遇:开发者视角的探讨

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; 近年来&#xff0c;鸿蒙系统&#xff08;HarmonyOS&#xff09;的发展备受瞩目。随着其在智能手机、智能穿戴、车载系统和智能家居等领域的广泛应用&#xff0c;鸿蒙系统正逐渐形成与安卓、iOS并列的三足鼎立…...

MySQL初学之旅(1)配置与基础操作

目录 1.前言 2.正文 2.1数据库的发展历程 2.2数据库的基础操作 2.2.1启动服务 2.2.2创建与删除数据库 2.2.3数据类型 2.2.4创建表与删除表 2.3MySQL Workbench基础使用简介 3.小结 1.前言 哈喽大家好吖&#xff0c;今天博主正式开始为大家分享数据库的学习&#xff…...

一款革命性的视频剪辑工具,AI剪辑新纪元:Clapper

如果说AI视频剪辑工具哪家强&#xff1f;还真想不出有什么让人眼前一亮的AI视频剪辑应用。 毕竟随着AI技术的发展越来越快&#xff0c;各种AI应用如雨后春笋般涌现&#xff0c;然而&#xff0c;真正能够在视频剪辑领域脱颖而出的工具却寥寥无几。 今天我要介绍的 Clapper 就是…...

HTML 区块

HTML 区块 HTML&#xff08;HyperText Markup Language&#xff09;是构建网页的标准语言&#xff0c;它定义了网页的结构和内容。在HTML中&#xff0c;区块元素是指那些能够定义较大块状结构的元素&#xff0c;比如段落、标题、列表、表格和 divis 等。这些元素通常对页面的布…...

复杂度的讲解

数据结构可以简单理解为在内存中管理数据 它具有速度快 带电存储的特点&#xff08;临时存储&#xff09; 如何衡量一个算法的好坏 因此衡量一个算法的好坏&#xff0c;一般是从时间和空间两个维度来衡量的&#xff0c;即时间复杂度和空间复杂度。 时间复杂度主要衡量一个算…...

[ Linux 命令基础 2 ] Linux 命令详解-系统管理命令

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…...

使用docker部署Prometheus和Grafana去监控mysql和redis

自动化性能监控系统安装部署 相关工具的安装部署 服务工具分配 服务器工具端口10.0.20.9grafana300010.0.20.9prometheus909010.0.20.10mysql330610.0.20.10mysql-exporter910410.0.20.10redis330610.0.20.10redis_exporter9121 使用docker-compose安装prometheus 先拉取p…...

日志管理 | Log360 实现PCI DSS v4.0数据安全合规要求

PCI DSS 是一项网络安全标准&#xff0c;得到所有主要信用卡和支付处理公司的支持&#xff0c;旨在确保信用卡和借记卡号码的安全。最新的PCI DSS v4.0 代表支付卡行业数据安全标准。 任何依赖信用卡交易的企业都不能将数字安全视为一个偷工减料的领域&#xff0c;因为数据泄露…...

JAVA中的string和stringbuffer

【之前面试测试岗位的时候有被问到这个问题&#xff0c;面试结束后特地来学习一下】 目录 谁先被提出的String的使用StringBuffer的使用两者区别 谁先被提出的 String类先于StringBuffer被提出&#xff0c;作为Java语言的基础部分&#xff0c;而StringBuffer是为了解决实际开…...

轻型民用无人驾驶航空器安全操控------理论考试多旋翼部分笔记

官网&#xff1a;民用无人驾驶航空器综合管理平台 (caac.gov.cn) 说明&#xff1a;一是法规部分&#xff1b;二是多旋翼部分 本笔记全部来源于轻型民用无人驾驶航空器安全操控视频讲解平台 目录 官网&#xff1a;民用无人驾驶航空器综合管理平台 (caac.gov.cn) 一、轻型民用无人…...

计算用户订购率梧桐数据库和oracle数据库sql分析

一、背景说明 移动运营商平台提供多种类型的产品权益&#xff0c;用户可以通过订购来使用。平台需要定期统计各个产品的用户订购情况&#xff0c;以便了解各个产品的受欢迎程度。这些统计数据将用于优化产品、提升用户体验和制定市场推广策略。 二、表结构说明 梧桐数据库建…...

通过DNS服务器架构解释DNS请求过程

在前面的章节,这里,基于PCAP数据包和RFC文档详细介绍了DNS请求和响应的每个字段的含义。但是在现实的网络世界中,DNS请求和响应的数据包是怎么流动的,会经过哪些设备。本文将着重说明一下目前网络空间中DNS请求和响应的流动过程。 当前网络空间中比较常见DNS请求的流程如下…...

OKG Research:用户意图驱动的Web3应用变革

出品&#xff5c; OKG Research 作者&#xff5c;Samuel QIN 当前加密市场的快速演变中&#xff0c;用户增长成为行业可持续发展的基石。目前主流观点在推动行业前进的路上&#xff0c;从单纯的技术探索在向更注重应用价值的方向转变。尽管近年来Web3生态系统发展迅速&#xf…...

hbase 工具类

hbase 工具类 pom.xml <dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>2.5.10-hadoop3</version> </dependency> <dependency><groupId>com.google.guava<…...

会议直击|美格智能受邀出席第三届无锡智能网联汽车生态大会,共筑汽车产业新质生产力

11月10日&#xff0c;2024世界物联网博览会分论坛——第三届无锡智能网联汽车生态大会在无锡举行&#xff0c;美格智能CEO杜国彬受邀出席&#xff0c;并参与“中央域控&#xff1a;重塑汽车智能架构的未来”主题圆桌论坛讨论&#xff0c;与行业伙伴共同探讨智能网联汽车产业领域…...

在 Jupyter Notebook 中使用 Matplotlib 进行交互式可视化的教程

在 Jupyter Notebook 中使用 Matplotlib 进行交互式可视化的教程 引言 数据可视化是数据分析的重要组成部分&#xff0c;能够帮助我们更直观地理解数据。Matplotlib 是 Python 中最流行的绘图库之一&#xff0c;而 Jupyter Notebook 则是进行数据分析和可视化的理想环境。本文…...

Android13 系统/用户证书安装相关分析总结(三) 增加安装系统证书的接口遇到的问题和坑

一、前言 接上回说到&#xff0c;修改了程序&#xff0c;增加了接口&#xff0c;却不知道有没有什么问题&#xff0c;于是心怀忐忑等了几天。果然过了几天&#xff0c;应用那边的小伙伴报过来了问题。用户证书安装没有问题&#xff0c;系统证书(新增的接口)还是出现了问题。调…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

分布式增量爬虫实现方案

之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面&#xff0c;避免重复抓取&#xff0c;以节省资源和时间。 在分布式环境下&#xff0c;增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路&#xff1a;将增量判…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

探索Selenium:自动化测试的神奇钥匙

目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...

Bean 作用域有哪些?如何答出技术深度?

导语&#xff1a; Spring 面试绕不开 Bean 的作用域问题&#xff0c;这是面试官考察候选人对 Spring 框架理解深度的常见方式。本文将围绕“Spring 中的 Bean 作用域”展开&#xff0c;结合典型面试题及实战场景&#xff0c;帮你厘清重点&#xff0c;打破模板式回答&#xff0c…...